// Copyright 2018 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/wake_on_wifi.h"

#include <errno.h>
#include <linux/nl80211.h>
#include <stdio.h>

#include <algorithm>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <base/cancelable_callback.h>
#include <base/strings/string_number_conversions.h>

#include <chromeos/dbus/service_constants.h>

#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/ip_address_store.h"
#include "shill/logging.h"
#include "shill/metrics.h"
#include "shill/net/event_history.h"
#include "shill/net/netlink_manager.h"
#include "shill/net/nl80211_message.h"
#include "shill/property_accessor.h"
#include "shill/wifi/wifi.h"

using base::Bind;
using base::Closure;
using std::pair;
using std::set;
using std::string;
using std::vector;


namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kWiFi;
static std::string ObjectID(WakeOnWiFi* w) { return "(wake_on_wifi)"; }
}

const char WakeOnWiFi::kWakeOnIPAddressPatternsNotSupported[] =
    "Wake on IP address patterns not supported by this WiFi device";
const char WakeOnWiFi::kWakeOnPatternsNotSupported[] =
    "Wake on patterns not supported by this WiFi device";
const char WakeOnWiFi::kMaxWakeOnPatternsReached[] =
    "Max number of patterns already registered";
const char WakeOnWiFi::kWakeOnWiFiNotSupported[] = "Wake on WiFi not supported";
const int WakeOnWiFi::kVerifyWakeOnWiFiSettingsDelayMilliseconds = 300;
const int WakeOnWiFi::kMaxSetWakeOnPacketRetries = 2;
const int WakeOnWiFi::kMetricsReportingFrequencySeconds = 600;
const uint32_t WakeOnWiFi::kDefaultWakeToScanPeriodSeconds = 900;
const uint32_t WakeOnWiFi::kDefaultNetDetectScanPeriodSeconds = 120;
const uint32_t WakeOnWiFi::kImmediateDHCPLeaseRenewalThresholdSeconds = 60;
// We tolerate no more than 3 dark resumes per minute and 10 dark resumes per
// 10 minutes  before we disable wake on WiFi on the NIC.
const int WakeOnWiFi::kDarkResumeFrequencySamplingPeriodShortMinutes = 1;
const int WakeOnWiFi::kDarkResumeFrequencySamplingPeriodLongMinutes = 10;
const int WakeOnWiFi::kMaxDarkResumesPerPeriodShort = 3;
const int WakeOnWiFi::kMaxDarkResumesPerPeriodLong = 10;
// If a connection is not established during dark resume, give up and prepare
// the system to wake on SSID 1 second before suspending again.
// TODO(samueltan): link this to
// Manager::kTerminationActionsTimeoutMilliseconds rather than hard-coding
// this value.
int64_t WakeOnWiFi::DarkResumeActionsTimeoutMilliseconds = 18500;
// Scanning 1 frequency takes ~100ms, so retrying 5 times on 8 frequencies will
// take about 4 seconds, which is how long a full scan typically takes.
const int WakeOnWiFi::kMaxFreqsForDarkResumeScanRetries = 8;
const int WakeOnWiFi::kMaxDarkResumeScanRetries = 5;
const char WakeOnWiFi::kWakeReasonStringPattern[] = "WiFi.Pattern";
const char WakeOnWiFi::kWakeReasonStringDisconnect[] = "WiFi.Disconnect";
const char WakeOnWiFi::kWakeReasonStringSSID[] = "WiFi.SSID";

WakeOnWiFi::WakeOnWiFi(
    NetlinkManager* netlink_manager, EventDispatcher* dispatcher,
    Metrics* metrics, const std::string& hardware_address,
    RecordWakeReasonCallback record_wake_reason_callback)
    : dispatcher_(dispatcher),
      netlink_manager_(netlink_manager),
      metrics_(metrics),
      report_metrics_callback_(
          Bind(&WakeOnWiFi::ReportMetrics, base::Unretained(this))),
      num_set_wake_on_packet_retries_(0),
      wake_on_wifi_max_patterns_(0),
      wake_on_wifi_max_ssids_(0),
      wiphy_index_(0),
      wiphy_index_received_(false),
#if defined(DISABLE_WAKE_ON_WIFI)
      wake_on_wifi_features_enabled_(kWakeOnWiFiFeaturesEnabledNotSupported),
#else
      // Wake on WiFi features disabled by default at run-time for boards that
      // support wake on WiFi. Rely on Chrome to enable appropriate features via
      // DBus.
      wake_on_wifi_features_enabled_(kWakeOnWiFiFeaturesEnabledNone),
#endif  // DISABLE_WAKE_ON_WIFI
      in_dark_resume_(false),
      wake_to_scan_period_seconds_(kDefaultWakeToScanPeriodSeconds),
      net_detect_scan_period_seconds_(kDefaultNetDetectScanPeriodSeconds),
      last_wake_reason_(kWakeTriggerUnsupported),
      force_wake_to_scan_timer_(false),
      dark_resume_scan_retries_left_(0),
      connected_before_suspend_(false),
      hardware_address_(hardware_address),
      min_pattern_len_(0),
      record_wake_reason_callback_(record_wake_reason_callback),
      weak_ptr_factory_(this) {
  netlink_handler_ = Bind(&WakeOnWiFi::OnWakeupReasonReceived,
      weak_ptr_factory_.GetWeakPtr());
  netlink_manager_->AddBroadcastHandler(netlink_handler_);
}

WakeOnWiFi::~WakeOnWiFi() {
  netlink_manager_->RemoveBroadcastHandler(netlink_handler_);
}

void WakeOnWiFi::InitPropertyStore(PropertyStore* store) {
  store->RegisterDerivedString(
      kWakeOnWiFiFeaturesEnabledProperty,
      StringAccessor(new CustomAccessor<WakeOnWiFi, string>(
          this, &WakeOnWiFi::GetWakeOnWiFiFeaturesEnabled,
          &WakeOnWiFi::SetWakeOnWiFiFeaturesEnabled)));
  store->RegisterUint32(kWakeToScanPeriodSecondsProperty,
                        &wake_to_scan_period_seconds_);
  store->RegisterUint32(kNetDetectScanPeriodSecondsProperty,
                        &net_detect_scan_period_seconds_);
  store->RegisterBool(kForceWakeToScanTimerProperty,
                      &force_wake_to_scan_timer_);
}

void WakeOnWiFi::StartMetricsTimer() {
#if !defined(DISABLE_WAKE_ON_WIFI)
  dispatcher_->PostDelayedTask(FROM_HERE, report_metrics_callback_.callback(),
                               kMetricsReportingFrequencySeconds * 1000);
#endif  // DISABLE_WAKE_ON_WIFI
}

string WakeOnWiFi::GetWakeOnWiFiFeaturesEnabled(Error* error) {
  return wake_on_wifi_features_enabled_;
}

bool WakeOnWiFi::SetWakeOnWiFiFeaturesEnabled(const std::string& enabled,
                                              Error* error) {
#if defined(DISABLE_WAKE_ON_WIFI)
  error->Populate(Error::kNotSupported, kWakeOnWiFiNotSupported);
  SLOG(this, 7) << __func__ << ": " << kWakeOnWiFiNotSupported;
  return false;
#else
  if (wake_on_wifi_features_enabled_ == enabled) {
    return false;
  }
  if (enabled != kWakeOnWiFiFeaturesEnabledPacket &&
      enabled != kWakeOnWiFiFeaturesEnabledDarkConnect &&
      enabled != kWakeOnWiFiFeaturesEnabledPacketDarkConnect &&
      enabled != kWakeOnWiFiFeaturesEnabledNone) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
                          "Invalid Wake on WiFi feature");
    return false;
  }
  wake_on_wifi_features_enabled_ = enabled;
  return true;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::RunAndResetSuspendActionsDoneCallback(const Error& error) {
  if (!suspend_actions_done_callback_.is_null()) {
    suspend_actions_done_callback_.Run(error);
    suspend_actions_done_callback_.Reset();
  }
}

// static
bool WakeOnWiFi::ByteStringPairIsLessThan(
    const std::pair<ByteString, ByteString>& lhs,
    const std::pair<ByteString, ByteString>& rhs) {
  // Treat the first value of the pair as the key.
  return ByteString::IsLessThan(lhs.first, rhs.first);
}

// static
void WakeOnWiFi::SetMask(
    ByteString* mask,
    const vector<LengthOffset>& patternlen_offset_pair,
    uint32_t expected_pat_len_bits) {
  // Round up number of bytes required for the mask.
  int result_mask_len = (expected_pat_len_bits + 8 - 1) / 8;
  vector<unsigned char> result_mask(result_mask_len, 0);
  // Set mask bits from offset to (pattern_len - 1)
  int mask_index;
  for (const auto& current_pair : patternlen_offset_pair) {
    for (uint32_t curr_mask_bit = current_pair.offset;
         curr_mask_bit < current_pair.length;
         ++curr_mask_bit) {
      mask_index = curr_mask_bit / 8;
      CHECK_LT(mask_index, result_mask_len);
      result_mask[mask_index] |= 1 << (curr_mask_bit % 8);
    }
  }
  mask->Clear();
  mask->Append(ByteString(result_mask));
}

// static
bool WakeOnWiFi::CreateIPAddressPatternAndMask(const IPAddress& ip_addr,
                                               uint32_t min_pattern_len,
                                               ByteString* pattern,
                                               ByteString* mask) {
  if (ip_addr.family() == IPAddress::kFamilyIPv4) {
    WakeOnWiFi::CreateIPV4PatternAndMask(
        ip_addr, min_pattern_len, pattern, mask);
    return true;
  } else if (ip_addr.family() == IPAddress::kFamilyIPv6) {
    WakeOnWiFi::CreateIPV6PatternAndMask(
        ip_addr, pattern, mask, min_pattern_len);
    return true;
  } else {
    LOG(ERROR) << "Unrecognized IP Address type.";
    return false;
  }
}

// static
bool WakeOnWiFi::ConvertIPProtoStrtoEnum(
    const std::vector<std::string>& ip_proto_strs,
    set<uint8_t>* ip_proto_enums,
    Error* error) {
  for (const auto& ip_proto : ip_proto_strs) {
    if (ip_proto == kWakeOnIP) {
      ip_proto_enums->insert(IPPROTO_IP);
    } else if (ip_proto == kWakeOnICMP) {
      ip_proto_enums->insert(IPPROTO_ICMP);
    } else if (ip_proto == kWakeOnIGMP) {
      ip_proto_enums->insert(IPPROTO_IGMP);
    } else if (ip_proto == kWakeOnIPIP) {
      ip_proto_enums->insert(IPPROTO_IPIP);
    } else if (ip_proto == kWakeOnTCP) {
      ip_proto_enums->insert(IPPROTO_TCP);
    } else if (ip_proto == kWakeOnUDP) {
      ip_proto_enums->insert(IPPROTO_UDP);
    } else if (ip_proto == kWakeOnIDP) {
      ip_proto_enums->insert(IPPROTO_IDP);
    } else {
      Error::PopulateAndLog(
          FROM_HERE,
          error,
          Error::kInvalidArguments,
          "Wake on Packet of type " + ip_proto + " not supported");
      return false;
    }
  }
  return true;
}

// static
string WakeOnWiFi::ConvertIPProtoEnumtoStr(uint8_t ip_proto_enum) {
  switch (ip_proto_enum) {
    case IPPROTO_IP:
      return kWakeOnIP;
    case IPPROTO_ICMP:
      return kWakeOnICMP;
    case IPPROTO_IGMP:
      return kWakeOnIGMP;
    case IPPROTO_IPIP:
      return kWakeOnIPIP;
    case IPPROTO_TCP:
      return kWakeOnTCP;
    case IPPROTO_UDP:
      return kWakeOnUDP;
    case IPPROTO_IDP:
      return kWakeOnIDP;
    default:
      return "";
  }
}

// static
void WakeOnWiFi::CreateIPV4PatternAndMask(const IPAddress& ip_addr,
                                          uint32_t min_pattern_len,
                                          ByteString* pattern,
                                          ByteString* mask) {
  struct {
    struct ethhdr eth_hdr;
    struct iphdr ipv4_hdr;
  } __attribute__((__packed__)) pattern_bytes;
  memset(&pattern_bytes, 0, sizeof(pattern_bytes));
  CHECK_EQ(sizeof(pattern_bytes.ipv4_hdr.saddr), ip_addr.GetLength());
  memcpy(&pattern_bytes.ipv4_hdr.saddr,
         ip_addr.GetConstData(),
         ip_addr.GetLength());
  int src_ip_offset =
      reinterpret_cast<unsigned char*>(&pattern_bytes.ipv4_hdr.saddr) -
      reinterpret_cast<unsigned char*>(&pattern_bytes);
  uint32_t pattern_len = src_ip_offset + ip_addr.GetLength();
  // If the length of the final pattern is less than min pattern length,
  // fill the rest with zeros.
  uint32_t expected_pattern_len = std::max(min_pattern_len, pattern_len);
  pattern->Clear();
  pattern->Append(
      ByteString(reinterpret_cast<const unsigned char*>(&pattern_bytes),
                 expected_pattern_len));
  vector<LengthOffset> patternlen_offset_pair;
  patternlen_offset_pair.emplace_back(pattern_len, src_ip_offset);
  WakeOnWiFi::SetMask(mask, patternlen_offset_pair, expected_pattern_len);
}

// static
void WakeOnWiFi::CreateIPV6PatternAndMask(const IPAddress& ip_addr,
                                          ByteString* pattern,
                                          ByteString* mask,
                                          uint32_t min_pattern_len) {
  struct {
    struct ethhdr eth_hdr;
    struct ip6_hdr ipv6_hdr;
  } __attribute__((__packed__)) pattern_bytes;
  memset(&pattern_bytes, 0, sizeof(pattern_bytes));
  CHECK_EQ(sizeof(pattern_bytes.ipv6_hdr.ip6_src), ip_addr.GetLength());
  memcpy(&pattern_bytes.ipv6_hdr.ip6_src,
         ip_addr.GetConstData(),
         ip_addr.GetLength());
  int src_ip_offset =
      reinterpret_cast<unsigned char*>(&pattern_bytes.ipv6_hdr.ip6_src) -
      reinterpret_cast<unsigned char*>(&pattern_bytes);
  uint32_t pattern_len = src_ip_offset + ip_addr.GetLength();
  uint32_t expected_pattern_len = std::max(min_pattern_len, pattern_len);
  pattern->Clear();
  pattern->Append(
      ByteString(reinterpret_cast<const unsigned char*>(&pattern_bytes),
                 expected_pattern_len));
  vector<LengthOffset> patternlen_offset_pair;
  patternlen_offset_pair.emplace_back(pattern_len, src_ip_offset);
  WakeOnWiFi::SetMask(mask, patternlen_offset_pair, expected_pattern_len);
}

// static
void WakeOnWiFi::CreatePacketTypePatternAndMaskforIPV4(
    const std::string& hardware_address,
    uint32_t min_pattern_len,
    uint8_t ip_protocol,
    ByteString* pattern,
    ByteString* mask) {
  struct Pattern {
    struct ethhdr eth_hdr;
    struct iphdr ipv4_hdr;
  } __attribute__((__packed__)) pattern_bytes;
  vector<LengthOffset> patternlen_offset_pair;
  memset(&pattern_bytes, 0, sizeof(pattern_bytes));
  vector<uint8_t> address_bytes;
  static_assert(std::is_standard_layout<Pattern>::value,
                  "Pattern must be a standard layout type");
  CHECK(base::HexStringToBytes(hardware_address, &address_bytes));
  CHECK_EQ(sizeof(pattern_bytes.eth_hdr.h_dest), address_bytes.size());
  std::copy(
      address_bytes.begin(), address_bytes.end(), pattern_bytes.eth_hdr.h_dest);
  uint32_t dst_hardware_offset = offsetof(Pattern, eth_hdr.h_dest);
  uint32_t pattern_len = dst_hardware_offset + address_bytes.size();
  patternlen_offset_pair.emplace_back(pattern_len, dst_hardware_offset);
  uint32_t eth_protocol_offset = offsetof(Pattern, eth_hdr.h_proto);
  pattern_bytes.eth_hdr.h_proto = htons(ETH_P_IP);
  uint32_t eth_protocol_len =
      eth_protocol_offset + sizeof(pattern_bytes.eth_hdr.h_proto);
  patternlen_offset_pair.emplace_back(eth_protocol_len, eth_protocol_offset);
  pattern_len = std::max(pattern_len, eth_protocol_len);
  pattern_bytes.ipv4_hdr.protocol = ip_protocol;
  uint32_t ip_protocol_offset = offsetof(Pattern, ipv4_hdr.protocol);
  uint32_t ip_protocol_pattern_len =
      ip_protocol_offset + sizeof(pattern_bytes.ipv4_hdr.protocol);
  patternlen_offset_pair.emplace_back(ip_protocol_pattern_len,
                                      ip_protocol_offset);
  pattern_len = std::max(pattern_len, ip_protocol_pattern_len);
  uint32_t expected_pattern_len = std::max(min_pattern_len, pattern_len);
  pattern->Clear();
  pattern->Append(
      ByteString(reinterpret_cast<const unsigned char*>(&pattern_bytes),
                 expected_pattern_len));
  WakeOnWiFi::SetMask(mask, patternlen_offset_pair, expected_pattern_len);
}

// static
void WakeOnWiFi::CreatePacketTypePatternAndMaskforIPV6(
    const std::string& hardware_address,
    uint32_t min_pattern_len,
    uint8_t ip_protocol,
    ByteString* pattern,
    ByteString* mask) {
  struct Pattern {
    struct ethhdr eth_hdr;
    struct ip6_hdr ipv6_hdr;
  } __attribute__((__packed__)) pattern_bytes;
  vector<LengthOffset> patternlen_offset_pair;
  static_assert(std::is_standard_layout<Pattern>::value,
                "Pattern must be a standard layout type");
  memset(&pattern_bytes, 0, sizeof(pattern_bytes));
  vector<uint8_t> address_bytes;
  CHECK(base::HexStringToBytes(hardware_address, &address_bytes));
  CHECK_EQ(sizeof(pattern_bytes.eth_hdr.h_dest), address_bytes.size());
  std::copy(
      address_bytes.begin(), address_bytes.end(), pattern_bytes.eth_hdr.h_dest);
  uint32_t dst_hardware_offset = offsetof(Pattern, eth_hdr.h_dest);
  uint32_t pattern_len = dst_hardware_offset + address_bytes.size();
  patternlen_offset_pair.emplace_back(pattern_len, dst_hardware_offset);
  uint32_t eth_protocol_offset = offsetof(Pattern, eth_hdr.h_proto);
  pattern_bytes.eth_hdr.h_proto = htons(ETH_P_IPV6);
  uint32_t eth_protocol_len =
      eth_protocol_offset + sizeof(pattern_bytes.eth_hdr.h_proto);
  patternlen_offset_pair.emplace_back(eth_protocol_len, eth_protocol_offset);
  pattern_len = std::max(pattern_len, eth_protocol_len);
  pattern_bytes.ipv6_hdr.ip6_ctlun.ip6_un1.ip6_un1_nxt = ip_protocol;
  uint32_t ip_protocol_offset =
      offsetof(Pattern, ipv6_hdr.ip6_ctlun.ip6_un1.ip6_un1_nxt);
  uint32_t ip_protocol_pattern_len =
      ip_protocol_offset +
      sizeof(pattern_bytes.ipv6_hdr.ip6_ctlun.ip6_un1.ip6_un1_nxt);
  patternlen_offset_pair.emplace_back(
      ip_protocol_pattern_len, ip_protocol_offset);
  pattern_len = std::max(pattern_len, ip_protocol_pattern_len);
  uint32_t expected_pattern_len = std::max(min_pattern_len, pattern_len);
  pattern->Clear();
  pattern->Append(
      ByteString(reinterpret_cast<const unsigned char*>(&pattern_bytes),
                 expected_pattern_len));
  WakeOnWiFi::SetMask(mask, patternlen_offset_pair, expected_pattern_len);
}

// static
bool WakeOnWiFi::ConfigureWiphyIndex(Nl80211Message* msg, int32_t index) {
  if (!msg->attributes()->CreateU32Attribute(NL80211_ATTR_WIPHY,
                                             "WIPHY index")) {
    return false;
  }
  if (!msg->attributes()->SetU32AttributeValue(NL80211_ATTR_WIPHY, index)) {
    return false;
  }
  return true;
}

// static
bool WakeOnWiFi::ConfigureDisableWakeOnWiFiMessage(
    SetWakeOnPacketConnMessage* msg, uint32_t wiphy_index, Error* error) {
  if (!ConfigureWiphyIndex(msg, wiphy_index)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Failed to configure Wiphy index.");
    return false;
  }
  return true;
}

// static
bool WakeOnWiFi::ConfigureSetWakeOnWiFiSettingsMessage(
    SetWakeOnPacketConnMessage* msg, const set<WakeOnWiFiTrigger>& trigs,
    const IPAddressStore& addrs, uint32_t wiphy_index,
    const set<uint8_t>& wake_on_packet_types,
    const std::string& hardware_address,
    uint32_t pattern_min_len, uint32_t net_detect_scan_period_seconds,
    const vector<ByteString>& ssid_whitelist, Error* error) {
#if defined(DISABLE_WAKE_ON_WIFI)
  return false;
#else
  if (trigs.empty()) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
                          "No triggers to configure.");
    return false;
  }
  if (base::ContainsKey(trigs, kWakeTriggerPattern) && addrs.Empty() &&
      wake_on_packet_types.empty()) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
                          "No IP addresses to configure.");
    return false;
  }
  if (!ConfigureWiphyIndex(msg, wiphy_index)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Failed to configure Wiphy index.");
    return false;
  }
  if (!msg->attributes()->CreateNestedAttribute(NL80211_ATTR_WOWLAN_TRIGGERS,
                                                "WoWLAN Triggers")) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not create nested attribute "
                          "NL80211_ATTR_WOWLAN_TRIGGERS");
    return false;
  }
  if (!msg->attributes()->SetNestedAttributeHasAValue(
          NL80211_ATTR_WOWLAN_TRIGGERS)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not set nested attribute "
                          "NL80211_ATTR_WOWLAN_TRIGGERS");
    return false;
  }

  AttributeListRefPtr triggers;
  if (!msg->attributes()->GetNestedAttributeList(NL80211_ATTR_WOWLAN_TRIGGERS,
                                                 &triggers)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not get nested attribute list "
                          "NL80211_ATTR_WOWLAN_TRIGGERS");
    return false;
  }
  // Add triggers.
  for (WakeOnWiFiTrigger t : trigs) {
    switch (t) {
      case kWakeTriggerDisconnect: {
        if (!triggers->CreateFlagAttribute(NL80211_WOWLAN_TRIG_DISCONNECT,
                                           "Wake on Disconnect")) {
          LOG(ERROR) << __func__ << "Could not create flag attribute "
                                    "NL80211_WOWLAN_TRIG_DISCONNECT";
          return false;
        }
        if (!triggers->SetFlagAttributeValue(NL80211_WOWLAN_TRIG_DISCONNECT,
                                             true)) {
          LOG(ERROR) << __func__ << "Could not set flag attribute "
                                    "NL80211_WOWLAN_TRIG_DISCONNECT";
          return false;
        }
        break;
      }
      case kWakeTriggerPattern: {
        if (!triggers->CreateNestedAttribute(NL80211_WOWLAN_TRIG_PKT_PATTERN,
                                             "Pattern trigger")) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not create nested attribute "
                                "NL80211_WOWLAN_TRIG_PKT_PATTERN");
          return false;
        }
        if (!triggers->SetNestedAttributeHasAValue(
                NL80211_WOWLAN_TRIG_PKT_PATTERN)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not set nested attribute "
                                "NL80211_WOWLAN_TRIG_PKT_PATTERN");
          return false;
        }
        AttributeListRefPtr patterns;
        if (!triggers->GetNestedAttributeList(NL80211_WOWLAN_TRIG_PKT_PATTERN,
                                              &patterns)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not get nested attribute list "
                                "NL80211_WOWLAN_TRIG_PKT_PATTERN");
          return false;
        }
        uint8_t patnum = 1;
        ByteString pattern;
        ByteString mask;
        for (const IPAddress& addr : addrs.GetIPAddresses()) {
          CreateIPAddressPatternAndMask(addr, pattern_min_len, &pattern, &mask);
          if (!CreateSingleAttribute(
                  pattern, mask, patterns, patnum++, error)) {
            return false;
          }
        }
        if (!wake_on_packet_types.empty()) {
          for (auto packet_type : wake_on_packet_types) {
            CreatePacketTypePatternAndMaskforIPV4(hardware_address,
                                                    pattern_min_len,
                                                    packet_type,
                                                    &pattern,
                                                    &mask);
            if (!CreateSingleAttribute(
                    pattern, mask, patterns, patnum++, error)) {
              return false;
            }
            CreatePacketTypePatternAndMaskforIPV6(hardware_address,
                                                    pattern_min_len,
                                                    packet_type,
                                                    &pattern,
                                                    &mask);
            if (!CreateSingleAttribute(
                    pattern, mask, patterns, patnum++, error)) {
              return false;
            }
          }
        }
        break;
      }
      case kWakeTriggerSSID: {
        if (!triggers->CreateNestedAttribute(NL80211_WOWLAN_TRIG_NET_DETECT,
                                             "Wake on SSID trigger")) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not create nested attribute "
                                "NL80211_WOWLAN_TRIG_NET_DETECT");
          return false;
        }
        if (!triggers->SetNestedAttributeHasAValue(
                NL80211_WOWLAN_TRIG_NET_DETECT)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not set nested attribute "
                                "NL80211_WOWLAN_TRIG_NET_DETECT");
          return false;
        }
        AttributeListRefPtr scan_attributes;
        if (!triggers->GetNestedAttributeList(NL80211_WOWLAN_TRIG_NET_DETECT,
                                              &scan_attributes)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not get nested attribute list "
                                "NL80211_WOWLAN_TRIG_NET_DETECT");
          return false;
        }
        if (!scan_attributes->CreateU32Attribute(
                NL80211_ATTR_SCHED_SCAN_INTERVAL,
                "NL80211_ATTR_SCHED_SCAN_INTERVAL")) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not get create U32 attribute "
                                "NL80211_ATTR_SCHED_SCAN_INTERVAL");
          return false;
        }
        if (!scan_attributes->SetU32AttributeValue(
                NL80211_ATTR_SCHED_SCAN_INTERVAL,
                net_detect_scan_period_seconds * 1000)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not get set U32 attribute "
                                "NL80211_ATTR_SCHED_SCAN_INTERVAL");
          return false;
        }
        if (!scan_attributes->CreateNestedAttribute(
                NL80211_ATTR_SCHED_SCAN_MATCH,
                "NL80211_ATTR_SCHED_SCAN_MATCH")) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not create nested attribute list "
                                "NL80211_ATTR_SCHED_SCAN_MATCH");
          return false;
        }
        if (!scan_attributes->SetNestedAttributeHasAValue(
                NL80211_ATTR_SCHED_SCAN_MATCH)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not set nested attribute "
                                "NL80211_ATTR_SCAN_SSIDS");
          return false;
        }
        AttributeListRefPtr ssids;
        if (!scan_attributes->GetNestedAttributeList(
                NL80211_ATTR_SCHED_SCAN_MATCH, &ssids)) {
          Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                "Could not get nested attribute list "
                                "NL80211_ATTR_SCHED_SCAN_MATCH");
          return false;
        }
        int ssid_num = 0;
        for (const ByteString& ssid_bytes :
             ssid_whitelist) {
          if (!ssids->CreateNestedAttribute(
                  ssid_num, "NL80211_ATTR_SCHED_SCAN_MATCH_SINGLE")) {
            Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                  "Could not create nested attribute list "
                                  "NL80211_ATTR_SCHED_SCAN_MATCH_SINGLE");
            return false;
          }
          if (!ssids->SetNestedAttributeHasAValue(ssid_num)) {
            Error::PopulateAndLog(
                FROM_HERE, error, Error::kOperationFailed,
                "Could not set value for nested attribute list "
                "NL80211_ATTR_SCHED_SCAN_MATCH_SINGLE");
            return false;
          }
          AttributeListRefPtr single_ssid;
          if (!ssids->GetNestedAttributeList(ssid_num, &single_ssid)) {
            Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                                  "Could not get nested attribute list "
                                  "NL80211_ATTR_SCHED_SCAN_MATCH_SINGLE");
            return false;
          }
          if (!single_ssid->CreateRawAttribute(
                  NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
                  "NL80211_SCHED_SCAN_MATCH_ATTR_SSID")) {
            Error::PopulateAndLog(
                FROM_HERE, error, Error::kOperationFailed,
                "Could not create NL80211_SCHED_SCAN_MATCH_ATTR_SSID");
            return false;
          }
          if (!single_ssid->SetRawAttributeValue(
                  NL80211_SCHED_SCAN_MATCH_ATTR_SSID, ssid_bytes)) {
            Error::PopulateAndLog(
                FROM_HERE, error, Error::kOperationFailed,
                "Could not set NL80211_SCHED_SCAN_MATCH_ATTR_SSID");
            return false;
          }
          ++ssid_num;
        }
        break;
      }
      default: {
        LOG(ERROR) << __func__ << ": Unrecognized trigger";
        return false;
      }
    }
  }
  return true;
#endif  // DISABLE_WAKE_ON_WIFI
}

// static
bool WakeOnWiFi::CreateSingleAttribute(const ByteString& pattern,
                                       const ByteString& mask,
                                       AttributeListRefPtr patterns,
                                       uint8_t patnum,
                                       Error* error) {
  if (!patterns->CreateNestedAttribute(patnum, "Pattern info")) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not create nested attribute "
                          "patnum for SetWakeOnPacketConnMessage.");
    return false;
  }
  if (!patterns->SetNestedAttributeHasAValue(patnum)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not set nested attribute "
                          "patnum for SetWakeOnPacketConnMessage.");
    return false;
  }
  AttributeListRefPtr pattern_info;
  if (!patterns->GetNestedAttributeList(patnum, &pattern_info)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not get nested attribute list "
                          "patnum for SetWakeOnPacketConnMessage.");
    return false;
  }
  // Add mask.
  if (!pattern_info->CreateRawAttribute(NL80211_PKTPAT_MASK, "Mask")) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not add attribute NL80211_PKTPAT_MASK to "
                          "pattern_info.");
    return false;
  }
  if (!pattern_info->SetRawAttributeValue(NL80211_PKTPAT_MASK, mask)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not set attribute NL80211_PKTPAT_MASK in "
                          "pattern_info.");
    return false;
  }
  // Add pattern.
  if (!pattern_info->CreateRawAttribute(NL80211_PKTPAT_PATTERN, "Pattern")) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not add attribute NL80211_PKTPAT_PATTERN to "
                          "pattern_info.");
    return false;
  }
  if (!pattern_info->SetRawAttributeValue(NL80211_PKTPAT_PATTERN, pattern)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not set attribute NL80211_PKTPAT_PATTERN in "
                          "pattern_info.");
    return false;
  }
  // Add offset.
  if (!pattern_info->CreateU32Attribute(NL80211_PKTPAT_OFFSET, "Offset")) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not add attribute NL80211_PKTPAT_OFFSET to "
                          "pattern_info.");
    return false;
  }
  if (!pattern_info->SetU32AttributeValue(NL80211_PKTPAT_OFFSET, 0)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Could not set attribute NL80211_PKTPAT_OFFSET in "
                          "pattern_info.");
    return false;
  }
  return true;
}

// static
bool WakeOnWiFi::ConfigureGetWakeOnWiFiSettingsMessage(
    GetWakeOnPacketConnMessage* msg, uint32_t wiphy_index, Error* error) {
  if (!ConfigureWiphyIndex(msg, wiphy_index)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
                          "Failed to configure Wiphy index.");
    return false;
  }
  return true;
}

// static
bool WakeOnWiFi::WakeOnWiFiSettingsMatch(
    const Nl80211Message& msg, const set<WakeOnWiFiTrigger>& trigs,
    const IPAddressStore& addrs, uint32_t net_detect_scan_period_seconds,
    const set<uint8_t>& wake_on_packet_types,
    const std::string& hardware_address, uint32_t min_pattern_len,
    const vector<ByteString>& ssid_whitelist) {
#if defined(DISABLE_WAKE_ON_WIFI)
  return false;
#else
  if (msg.command() != NL80211_CMD_GET_WOWLAN &&
      msg.command() != NL80211_CMD_SET_WOWLAN) {
    LOG(ERROR) << __func__ << ": "
               << "Invalid message command";
    return false;
  }
  AttributeListConstRefPtr triggers;
  if (!msg.const_attributes()->ConstGetNestedAttributeList(
          NL80211_ATTR_WOWLAN_TRIGGERS, &triggers)) {
    // No triggers in the returned message, which is valid iff we expect there
    // to be no triggers programmed into the NIC.
    return trigs.empty();
  }
  // If we find a trigger in |msg| that we do not have a corresponding flag
  // for in |trigs|, we have a mismatch.
  bool unused_flag;
  AttributeListConstRefPtr unused_list;
  if (triggers->GetFlagAttributeValue(NL80211_WOWLAN_TRIG_DISCONNECT,
                                      &unused_flag) &&
      !base::ContainsKey(trigs, kWakeTriggerDisconnect)) {
    SLOG(WiFi, nullptr, 3)
        << __func__ << "Wake on disconnect trigger not expected but found";
    return false;
  }
  if (triggers->ConstGetNestedAttributeList(NL80211_WOWLAN_TRIG_PKT_PATTERN,
                                            &unused_list) &&
      !base::ContainsKey(trigs, kWakeTriggerPattern)) {
    SLOG(WiFi, nullptr, 3) << __func__
                           << "Wake on pattern trigger not expected but found";
    return false;
  }
  if (triggers->ConstGetNestedAttributeList(NL80211_WOWLAN_TRIG_NET_DETECT,
                                            &unused_list) &&
      !base::ContainsKey(trigs, kWakeTriggerSSID)) {
    SLOG(WiFi, nullptr, 3) << __func__
                           << "Wake on SSID trigger not expected but found";
    return false;
  }
  // Check that each expected trigger is present in |msg| with matching
  // setting values.
  for (WakeOnWiFiTrigger t : trigs) {
    switch (t) {
      case kWakeTriggerDisconnect: {
        bool wake_on_disconnect;
        if (!triggers->GetFlagAttributeValue(NL80211_WOWLAN_TRIG_DISCONNECT,
                                             &wake_on_disconnect)) {
          LOG(ERROR) << __func__ << ": "
                     << "Could not get the flag NL80211_WOWLAN_TRIG_DISCONNECT";
          return false;
        }
        if (!wake_on_disconnect) {
          SLOG(WiFi, nullptr, 3) << __func__
                                 << "Wake on disconnect flag not set.";
          return false;
        }
        break;
      }
      case kWakeTriggerPattern: {
        // Create pattern and masks that we expect to find in |msg|.
        set<pair<ByteString, ByteString>, decltype(&ByteStringPairIsLessThan)>
            expected_patt_mask_pairs(ByteStringPairIsLessThan);
        ByteString temp_pattern;
        ByteString temp_mask;
        for (const IPAddress& addr : addrs.GetIPAddresses()) {
          CreateIPAddressPatternAndMask(addr, min_pattern_len, &temp_pattern,
                                        &temp_mask);
          expected_patt_mask_pairs.emplace(temp_pattern, temp_mask);
        }
        if (!wake_on_packet_types.empty()) {
          for (auto packet_type : wake_on_packet_types) {
            CreatePacketTypePatternAndMaskforIPV4(hardware_address,
                                                    min_pattern_len,
                                                    packet_type,
                                                    &temp_pattern,
                                                    &temp_mask);
            expected_patt_mask_pairs.emplace(temp_pattern, temp_mask);
            CreatePacketTypePatternAndMaskforIPV6(hardware_address,
                                                    min_pattern_len,
                                                    packet_type,
                                                    &temp_pattern,
                                                    &temp_mask);
            expected_patt_mask_pairs.emplace(temp_pattern, temp_mask);
          }
        }
        // Check these expected pattern and masks against those actually
        // contained in |msg|.
        AttributeListConstRefPtr patterns;
        if (!triggers->ConstGetNestedAttributeList(
                NL80211_WOWLAN_TRIG_PKT_PATTERN, &patterns)) {
          LOG(ERROR) << __func__ << ": "
                     << "Could not get nested attribute list "
                        "NL80211_WOWLAN_TRIG_PKT_PATTERN";
          return false;
        }
        bool pattern_mismatch_found = false;
        size_t pattern_num_mismatch = expected_patt_mask_pairs.size();
        int pattern_index;
        AttributeIdIterator pattern_iter(*patterns);
        AttributeListConstRefPtr pattern_info;
        ByteString returned_mask;
        ByteString returned_pattern;
        while (!pattern_iter.AtEnd()) {
          returned_mask.Clear();
          returned_pattern.Clear();
          pattern_index = pattern_iter.GetId();
          if (!patterns->ConstGetNestedAttributeList(pattern_index,
                                                     &pattern_info)) {
            LOG(ERROR) << __func__ << ": "
                       << "Could not get nested pattern attribute list #"
                       << pattern_index;
            return false;
          }
          if (!pattern_info->GetRawAttributeValue(NL80211_PKTPAT_MASK,
                                                  &returned_mask)) {
            LOG(ERROR) << __func__ << ": "
                       << "Could not get attribute NL80211_PKTPAT_MASK";
            return false;
          }
          if (!pattern_info->GetRawAttributeValue(NL80211_PKTPAT_PATTERN,
                                                  &returned_pattern)) {
            LOG(ERROR) << __func__ << ": "
                       << "Could not get attribute NL80211_PKTPAT_PATTERN";
            return false;
          }
          if (!base::ContainsKey(
                  expected_patt_mask_pairs,
                  std::make_pair(returned_pattern, returned_mask))) {
            pattern_mismatch_found = true;
            break;
          } else {
            --pattern_num_mismatch;
          }
          pattern_iter.Advance();
        }
        if (pattern_mismatch_found || pattern_num_mismatch) {
          SLOG(WiFi, nullptr, 3) << __func__
                                 << "Wake on pattern pattern/mask mismatch";
          return false;
        }
        break;
      }
      case kWakeTriggerSSID: {
        set<ByteString, decltype(&ByteString::IsLessThan)> expected_ssids(
            ssid_whitelist.begin(), ssid_whitelist.end(),
            ByteString::IsLessThan);
        AttributeListConstRefPtr scan_attributes;
        if (!triggers->ConstGetNestedAttributeList(
                NL80211_WOWLAN_TRIG_NET_DETECT, &scan_attributes)) {
          LOG(ERROR) << __func__ << ": "
                     << "Could not get nested attribute list "
                        "NL80211_WOWLAN_TRIG_NET_DETECT";
          return false;
        }
        uint32_t interval;
        if (!scan_attributes->GetU32AttributeValue(
                NL80211_ATTR_SCHED_SCAN_INTERVAL, &interval)) {
          LOG(ERROR) << __func__ << ": "
                     << "Could not get set U32 attribute "
                        "NL80211_ATTR_SCHED_SCAN_INTERVAL";
          return false;
        }
        if (interval != net_detect_scan_period_seconds * 1000) {
          SLOG(WiFi, nullptr, 3) << __func__
                                 << "Net Detect scan period mismatch";
          return false;
        }
        AttributeListConstRefPtr ssids;
        if (!scan_attributes->ConstGetNestedAttributeList(
                NL80211_ATTR_SCHED_SCAN_MATCH, &ssids)) {
          LOG(ERROR) << __func__ << ": "
                     << "Could not get nested attribute list "
                        "NL80211_ATTR_SCHED_SCAN_MATCH";
          return false;
        }
        bool ssid_mismatch_found = false;
        size_t ssid_num_mismatch = expected_ssids.size();
        AttributeIdIterator ssid_iter(*ssids);
        AttributeListConstRefPtr single_ssid;
        ByteString ssid;
        int ssid_index;
        while (!ssid_iter.AtEnd()) {
          ssid.Clear();
          ssid_index = ssid_iter.GetId();
          if (!ssids->ConstGetNestedAttributeList(ssid_index, &single_ssid)) {
            LOG(ERROR) << __func__ << ": "
                       << "Could not get nested ssid attribute list #"
                       << ssid_index;
            return false;
          }
          if (!single_ssid->GetRawAttributeValue(
                  NL80211_SCHED_SCAN_MATCH_ATTR_SSID, &ssid)) {
            LOG(ERROR) << __func__ << ": "
                       << "Could not get attribute "
                          "NL80211_SCHED_SCAN_MATCH_ATTR_SSID";
            return false;
          }
          if (!base::ContainsKey(expected_ssids, ssid)) {
            ssid_mismatch_found = true;
            break;
          } else {
            --ssid_num_mismatch;
          }
          ssid_iter.Advance();
        }
        if (ssid_mismatch_found || ssid_num_mismatch) {
          SLOG(WiFi, nullptr, 3) << __func__ << "Net Detect SSID mismatch";
          return false;
        }
        break;
      }
      default: {
        LOG(ERROR) << __func__ << ": Unrecognized trigger";
        return false;
      }
    }
  }
  return true;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::AddWakeOnPacketConnection(const string& ip_endpoint,
                                           Error* error) {
#if !defined(DISABLE_WAKE_ON_WIFI)
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerPattern)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
                          kWakeOnIPAddressPatternsNotSupported);
    return;
  }
  IPAddress ip_addr(ip_endpoint);
  if (!ip_addr.IsValid()) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
                          "Invalid ip_address " + ip_endpoint);
    return;
  }

  if (wake_on_packet_connections_.Count() +
      wake_on_packet_types_.size() >= wake_on_wifi_max_patterns_) {
    Error::PopulateAndLog(
        FROM_HERE, error, Error::kOperationFailed,
        "Max number of IP address patterns already registered");
    return;
  }
  wake_on_packet_connections_.AddUnique(ip_addr);
#else
  error->Populate(Error::kNotSupported, kWakeOnWiFiNotSupported);
  SLOG(this, 7) << __func__ << ": " << kWakeOnWiFiNotSupported;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::AddWakeOnPacketOfTypes(
    const std::vector<std::string>& packet_types, Error* error) {
#if !defined(DISABLE_WAKE_ON_WIFI)
  set<uint8_t> ip_proto_enums;
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerPattern)) {
    Error::PopulateAndLog(
        FROM_HERE, error, Error::kNotSupported, kWakeOnPatternsNotSupported);
    return;
  }
  // We should add 1 pattern for IPv4 and one for IPv6 for each packet type.
  int num_patterns_for_packet_types = packet_types.size() * 2;
  if (wake_on_packet_connections_.Count() + num_patterns_for_packet_types >=
      wake_on_wifi_max_patterns_) {
    Error::PopulateAndLog(
        FROM_HERE, error, Error::kOperationFailed, kMaxWakeOnPatternsReached);
    return;
  }
  if (!ConvertIPProtoStrtoEnum(packet_types, &ip_proto_enums, error))
    return;
  wake_on_packet_types_.insert(ip_proto_enums.begin(), ip_proto_enums.end());
#else
  error->Populate(Error::kNotSupported, kWakeOnWiFiNotSupported);
  SLOG(this, 7) << __func__ << ": " << kWakeOnWiFiNotSupported;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::RemoveWakeOnPacketConnection(const string& ip_endpoint,
                                              Error* error) {
#if !defined(DISABLE_WAKE_ON_WIFI)
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerPattern)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
                          kWakeOnIPAddressPatternsNotSupported);
    return;
  }
  IPAddress ip_addr(ip_endpoint);
  if (!ip_addr.IsValid()) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
                          "Invalid ip_address " + ip_endpoint);
    return;
  }
  if (!wake_on_packet_connections_.Contains(ip_addr)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kNotFound,
                          "No such IP address match registered to wake device");
    return;
  }
  wake_on_packet_connections_.Remove(ip_addr);
#else
  error->Populate(Error::kNotSupported, kWakeOnWiFiNotSupported);
  SLOG(this, 7) << __func__ << ": " << kWakeOnWiFiNotSupported;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::RemoveWakeOnPacketOfTypes(
    const std::vector<std::string>& packet_types, Error* error) {
#if !defined(DISABLE_WAKE_ON_WIFI)
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerPattern)) {
    Error::PopulateAndLog(
        FROM_HERE, error, Error::kNotSupported, kWakeOnPatternsNotSupported);
    return;
  }

  set<uint8_t> ip_proto_enums;
  if (!ConvertIPProtoStrtoEnum(packet_types, &ip_proto_enums, error))
    return;

  for (auto ip_proto_enum : ip_proto_enums) {
    if (base::ContainsKey(wake_on_packet_types_, ip_proto_enum))
      wake_on_packet_types_.erase(ip_proto_enum);
  }


#else
  error->Populate(Error::kNotSupported, kWakeOnWiFiNotSupported);
  SLOG(this, 7) << __func__ << ": " << kWakeOnWiFiNotSupported;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::RemoveAllWakeOnPacketConnections(Error* error) {
#if !defined(DISABLE_WAKE_ON_WIFI)
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerPattern)) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kNotSupported,
                          kWakeOnIPAddressPatternsNotSupported);
    return;
  }
  wake_on_packet_connections_.Clear();
  wake_on_packet_types_.clear();

#else
  error->Populate(Error::kNotSupported, kWakeOnWiFiNotSupported);
  SLOG(this, 7) << __func__ << ": " << kWakeOnWiFiNotSupported;
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::OnWakeOnWiFiSettingsErrorResponse(
    NetlinkManager::AuxilliaryMessageType type,
    const NetlinkMessage* raw_message) {
  Error error(Error::kOperationFailed);
  switch (type) {
    case NetlinkManager::kErrorFromKernel:
      if (!raw_message) {
        error.Populate(Error::kOperationFailed, "Unknown error from kernel");
        break;
      }
      if (raw_message->message_type() == ErrorAckMessage::GetMessageType()) {
        const ErrorAckMessage* error_ack_message =
            static_cast<const ErrorAckMessage*>(raw_message);
        if (error_ack_message->error() == EOPNOTSUPP) {
          error.Populate(Error::kNotSupported);
        }
      }
      break;

    case NetlinkManager::kUnexpectedResponseType:
      error.Populate(Error::kNotRegistered,
                     "Message not handled by regular message handler:");
      break;

    case NetlinkManager::kTimeoutWaitingForResponse:
      // CMD_SET_WOWLAN messages do not receive responses, so this error type
      // is received when NetlinkManager times out the message handler. Return
      // immediately rather than run the done callback since this event does
      // not signify the completion of suspend actions.
      return;
      break;

    default:
      error.Populate(
          Error::kOperationFailed,
          "Unexpected auxilliary message type: " + std::to_string(type));
      break;
  }
  RunAndResetSuspendActionsDoneCallback(error);
}

// static
void WakeOnWiFi::OnSetWakeOnPacketConnectionResponse(
    const Nl80211Message& nl80211_message) {
  // NOP because kernel does not send a response to NL80211_CMD_SET_WOWLAN
  // requests.
}

void WakeOnWiFi::RequestWakeOnPacketSettings() {
  SLOG(this, 3) << __func__;
  Error e;
  GetWakeOnPacketConnMessage get_wowlan_msg;
  CHECK(wiphy_index_received_);
  if (!ConfigureGetWakeOnWiFiSettingsMessage(&get_wowlan_msg, wiphy_index_,
                                             &e)) {
    LOG(ERROR) << e.message();
    return;
  }
  netlink_manager_->SendNl80211Message(
      &get_wowlan_msg, Bind(&WakeOnWiFi::VerifyWakeOnWiFiSettings,
                            weak_ptr_factory_.GetWeakPtr()),
      Bind(&NetlinkManager::OnAckDoNothing),
      Bind(&NetlinkManager::OnNetlinkMessageError));
}

void WakeOnWiFi::VerifyWakeOnWiFiSettings(
    const Nl80211Message& nl80211_message) {
  SLOG(this, 3) << __func__;
  if (WakeOnWiFiSettingsMatch(nl80211_message, wake_on_wifi_triggers_,
                              wake_on_packet_connections_,
                              net_detect_scan_period_seconds_,
                              wake_on_packet_types_, hardware_address_,
                              min_pattern_len_, wake_on_ssid_whitelist_)) {
    SLOG(this, 2) << __func__ << ": "
                  << "Wake on WiFi settings successfully verified";
    metrics_->NotifyVerifyWakeOnWiFiSettingsResult(
        Metrics::kVerifyWakeOnWiFiSettingsResultSuccess);
    RunAndResetSuspendActionsDoneCallback(Error(Error::kSuccess));
  } else {
    LOG(ERROR) << __func__ << " failed: discrepancy between wake-on-packet "
                              "settings on NIC and those in local data "
                              "structure detected";
    metrics_->NotifyVerifyWakeOnWiFiSettingsResult(
        Metrics::kVerifyWakeOnWiFiSettingsResultFailure);
    RetrySetWakeOnPacketConnections();
  }
}

void WakeOnWiFi::ApplyWakeOnWiFiSettings() {
  SLOG(this, 3) << __func__;
  if (!wiphy_index_received_) {
    LOG(ERROR) << "Interface index not yet received";
    return;
  }
  if (wake_on_wifi_triggers_.empty()) {
    SLOG(this, 1) << "No triggers to be programmed, so disable wake on WiFi";
    DisableWakeOnWiFi();
    return;
  }
  Error error;
  SetWakeOnPacketConnMessage set_wowlan_msg;
  if (!ConfigureSetWakeOnWiFiSettingsMessage(
          &set_wowlan_msg, wake_on_wifi_triggers_, wake_on_packet_connections_,
          wiphy_index_, wake_on_packet_types_, hardware_address_,
          min_pattern_len_, net_detect_scan_period_seconds_,
          wake_on_ssid_whitelist_, &error)) {
    LOG(ERROR) << error.message();
    RunAndResetSuspendActionsDoneCallback(
        Error(Error::kOperationFailed, error.message()));
    return;
  }
  if (!netlink_manager_->SendNl80211Message(
          &set_wowlan_msg,
          Bind(&WakeOnWiFi::OnSetWakeOnPacketConnectionResponse),
          Bind(&NetlinkManager::OnAckDoNothing),
          Bind(&WakeOnWiFi::OnWakeOnWiFiSettingsErrorResponse,
               weak_ptr_factory_.GetWeakPtr()))) {
    RunAndResetSuspendActionsDoneCallback(
        Error(Error::kOperationFailed, "SendNl80211Message failed"));
    return;
  }

  verify_wake_on_packet_settings_callback_.Reset(
      Bind(&WakeOnWiFi::RequestWakeOnPacketSettings,
           weak_ptr_factory_.GetWeakPtr()));
  dispatcher_->PostDelayedTask(FROM_HERE,
      verify_wake_on_packet_settings_callback_.callback(),
      kVerifyWakeOnWiFiSettingsDelayMilliseconds);
}

void WakeOnWiFi::DisableWakeOnWiFi() {
  SLOG(this, 3) << __func__;
  Error error;
  SetWakeOnPacketConnMessage disable_wowlan_msg;
  CHECK(wiphy_index_received_);
  if (!ConfigureDisableWakeOnWiFiMessage(&disable_wowlan_msg, wiphy_index_,
                                         &error)) {
    LOG(ERROR) << error.message();
    RunAndResetSuspendActionsDoneCallback(
        Error(Error::kOperationFailed, error.message()));
    return;
  }
  wake_on_wifi_triggers_.clear();
  if (!netlink_manager_->SendNl80211Message(
          &disable_wowlan_msg,
          Bind(&WakeOnWiFi::OnSetWakeOnPacketConnectionResponse),
          Bind(&NetlinkManager::OnAckDoNothing),
          Bind(&WakeOnWiFi::OnWakeOnWiFiSettingsErrorResponse,
               weak_ptr_factory_.GetWeakPtr()))) {
    RunAndResetSuspendActionsDoneCallback(
        Error(Error::kOperationFailed, "SendNl80211Message failed"));
    return;
  }

  verify_wake_on_packet_settings_callback_.Reset(
      Bind(&WakeOnWiFi::RequestWakeOnPacketSettings,
           weak_ptr_factory_.GetWeakPtr()));
  dispatcher_->PostDelayedTask(FROM_HERE,
      verify_wake_on_packet_settings_callback_.callback(),
      kVerifyWakeOnWiFiSettingsDelayMilliseconds);
}

void WakeOnWiFi::RetrySetWakeOnPacketConnections() {
  SLOG(this, 3) << __func__;
  if (num_set_wake_on_packet_retries_ < kMaxSetWakeOnPacketRetries) {
    ApplyWakeOnWiFiSettings();
    ++num_set_wake_on_packet_retries_;
  } else {
    SLOG(this, 3) << __func__ << ": max retry attempts reached";
    num_set_wake_on_packet_retries_ = 0;
    RunAndResetSuspendActionsDoneCallback(Error(Error::kOperationFailed));
  }
}

bool WakeOnWiFi::WakeOnWiFiPacketEnabledAndSupported() {
  if (wake_on_wifi_features_enabled_ == kWakeOnWiFiFeaturesEnabledNone ||
      wake_on_wifi_features_enabled_ ==
          kWakeOnWiFiFeaturesEnabledNotSupported ||
      wake_on_wifi_features_enabled_ == kWakeOnWiFiFeaturesEnabledDarkConnect) {
    return false;
  }
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerPattern)) {
    return false;
  }
  return true;
}

bool WakeOnWiFi::WakeOnWiFiDarkConnectEnabledAndSupported() {
  if (wake_on_wifi_features_enabled_ == kWakeOnWiFiFeaturesEnabledNone ||
      wake_on_wifi_features_enabled_ ==
          kWakeOnWiFiFeaturesEnabledNotSupported ||
      wake_on_wifi_features_enabled_ == kWakeOnWiFiFeaturesEnabledPacket) {
    return false;
  }
  if (!base::ContainsKey(wake_on_wifi_triggers_supported_,
                         kWakeTriggerDisconnect) ||
      !base::ContainsKey(wake_on_wifi_triggers_supported_, kWakeTriggerSSID)) {
    return false;
  }
  return true;
}

void WakeOnWiFi::ReportMetrics() {
  Metrics::WakeOnWiFiFeaturesEnabledState reported_state;
  if (wake_on_wifi_features_enabled_ == kWakeOnWiFiFeaturesEnabledNone) {
    reported_state = Metrics::kWakeOnWiFiFeaturesEnabledStateNone;
  } else if (wake_on_wifi_features_enabled_ ==
             kWakeOnWiFiFeaturesEnabledPacket) {
    reported_state = Metrics::kWakeOnWiFiFeaturesEnabledStatePacket;
  } else if (wake_on_wifi_features_enabled_ ==
             kWakeOnWiFiFeaturesEnabledDarkConnect) {
    reported_state = Metrics::kWakeOnWiFiFeaturesEnabledStateDarkConnect;
  } else if (wake_on_wifi_features_enabled_ ==
             kWakeOnWiFiFeaturesEnabledPacketDarkConnect) {
    reported_state = Metrics::kWakeOnWiFiFeaturesEnabledStatePacketDarkConnect;
  } else {
    LOG(ERROR) << __func__ << ": "
               << "Invalid wake on WiFi features state";
    return;
  }
  metrics_->NotifyWakeOnWiFiFeaturesEnabledState(reported_state);
  StartMetricsTimer();
}

void WakeOnWiFi::ParseWakeOnWiFiCapabilities(
    const Nl80211Message& nl80211_message) {
  // Verify NL80211_CMD_NEW_WIPHY.
#if !defined(DISABLE_WAKE_ON_WIFI)
  if (nl80211_message.command() != NewWiphyMessage::kCommand) {
    LOG(ERROR) << "Received unexpected command:" << nl80211_message.command();
    return;
  }
  AttributeListConstRefPtr triggers_supported;
  if (nl80211_message.const_attributes()->ConstGetNestedAttributeList(
      NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, &triggers_supported)) {
    bool disconnect_supported = false;
    if (triggers_supported->GetFlagAttributeValue(
        NL80211_WOWLAN_TRIG_DISCONNECT, &disconnect_supported)) {
      if (disconnect_supported) {
        wake_on_wifi_triggers_supported_.insert(
            WakeOnWiFi::kWakeTriggerDisconnect);
        SLOG(this, 7) << "Waking on disconnect supported by this WiFi device";
      }
    }
    ByteString pattern_data;
    if (triggers_supported->GetRawAttributeValue(
        NL80211_WOWLAN_TRIG_PKT_PATTERN, &pattern_data)) {
      struct nl80211_pattern_support* patt_support =
          reinterpret_cast<struct nl80211_pattern_support*>(
              pattern_data.GetData());
      // Determine the IPv4 and IPv6 pattern lengths we will use by
      // constructing dummy patterns and getting their lengths.
      ByteString dummy_pattern;
      ByteString dummy_mask;
      // Currently intel WiFi chip doesn't wake on min len patterns(b/62726471).
      // Adding 1 as a hack to fix this issue.
      // TODO(ravisadineni): Remove this check after b/62726471 is fixed.
      min_pattern_len_ = patt_support->min_pattern_len + 1;
      WakeOnWiFi::CreateIPV4PatternAndMask(IPAddress("192.168.0.20"),
                                           min_pattern_len_,
                                           &dummy_pattern,
                                           &dummy_mask);
      size_t ipv4_pattern_len = dummy_pattern.GetLength();
      WakeOnWiFi::CreateIPV6PatternAndMask(
          IPAddress("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210"),
          &dummy_pattern,
          &dummy_mask,
          min_pattern_len_);
      size_t ipv6_pattern_len = dummy_pattern.GetLength();
      WakeOnWiFi::CreatePacketTypePatternAndMaskforIPV4(hardware_address_,
                                                          min_pattern_len_,
                                                          IPPROTO_TCP,
                                                          &dummy_pattern,
                                                          &dummy_mask);
      size_t ipv4_packet_type_pattern_len = dummy_pattern.GetLength();
      WakeOnWiFi::CreatePacketTypePatternAndMaskforIPV6(hardware_address_,
                                                          min_pattern_len_,
                                                          IPPROTO_TCP,
                                                          &dummy_pattern,
                                                          &dummy_mask);
      size_t ipv6_packet_type_pattern_len = dummy_pattern.GetLength();
      size_t min_pattern_len = std::min({ipv4_pattern_len,
                                         ipv6_pattern_len,
                                         ipv4_packet_type_pattern_len,
                                         ipv6_packet_type_pattern_len});
      size_t max_pattern_len = std::max({ipv4_pattern_len,
                                         ipv6_pattern_len,
                                         ipv4_packet_type_pattern_len,
                                         ipv6_packet_type_pattern_len});
      // Check if the pattern matching capabilities of this WiFi device will
      // allow all possible patterns to be used.
      if (patt_support->min_pattern_len <= min_pattern_len &&
          patt_support->max_pattern_len >= max_pattern_len) {
        wake_on_wifi_triggers_supported_.insert(
            WakeOnWiFi::kWakeTriggerPattern);
        wake_on_wifi_max_patterns_ = patt_support->max_patterns;
        SLOG(this, 7) << "Waking on up to " << wake_on_wifi_max_patterns_
                      << " registered patterns of "
                      << patt_support->min_pattern_len << "-"
                      << patt_support->max_pattern_len
                      << " bytes supported by this WiFi device";
      }
    }
    if (triggers_supported->GetU32AttributeValue(NL80211_WOWLAN_TRIG_NET_DETECT,
                                                 &wake_on_wifi_max_ssids_)) {
      wake_on_wifi_triggers_supported_.insert(WakeOnWiFi::kWakeTriggerSSID);
      SLOG(this, 7) << "Waking on up to " << wake_on_wifi_max_ssids_
                    << " whitelisted SSIDs supported by this WiFi device";
    }
  }
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::OnWakeupReasonReceived(const NetlinkMessage& netlink_message) {
#if defined(DISABLE_WAKE_ON_WIFI)
  SLOG(this, 7) << __func__ << ": "
                << "Wake on WiFi not supported, so do nothing";
#else
  // We only handle wakeup reason messages in this handler, which is are
  // nl80211 messages with the NL80211_CMD_SET_WOWLAN command.
  if (netlink_message.message_type() != Nl80211Message::GetMessageType()) {
    SLOG(this, 7) << __func__ << ": "
                  << "Not a NL80211 Message";
    return;
  }
  const Nl80211Message& wakeup_reason_msg =
      *reinterpret_cast<const Nl80211Message*>(&netlink_message);
  if (wakeup_reason_msg.command() != SetWakeOnPacketConnMessage::kCommand) {
    SLOG(this, 7) << __func__ << ": "
                  << "Not a NL80211_CMD_SET_WOWLAN message";
    return;
  }
  uint32_t wiphy_index;
  if (!wakeup_reason_msg.const_attributes()->GetU32AttributeValue(
          NL80211_ATTR_WIPHY, &wiphy_index)) {
    LOG(ERROR) << "NL80211_CMD_NEW_WIPHY had no NL80211_ATTR_WIPHY";
    return;
  }
  if (!wiphy_index_received_) {
    SLOG(this, 7) << __func__ << ": "
                  << "Interface index not yet received";
    return;
  }
  if (wiphy_index != wiphy_index_) {
    SLOG(this, 7) << __func__ << ": "
                  << "Wakeup reason not meant for this interface";
    return;
  }
  metrics_->NotifyWakeupReasonReceived();
  SLOG(this, 3) << __func__ << ": "
                << "Parsing wakeup reason";
  AttributeListConstRefPtr triggers;
  if (!wakeup_reason_msg.const_attributes()->ConstGetNestedAttributeList(
          NL80211_ATTR_WOWLAN_TRIGGERS, &triggers)) {
    SLOG(this, 3) << __func__ << ": "
                  << "Wakeup reason: Not wake on WiFi related";
    return;
  }
  bool wake_flag;
  if (triggers->GetFlagAttributeValue(NL80211_WOWLAN_TRIG_DISCONNECT,
                                      &wake_flag)) {
    SLOG(this, 3) << __func__ << ": "
                  << "Wakeup reason: Disconnect";
    last_wake_reason_ = kWakeTriggerDisconnect;
    record_wake_reason_callback_.Run(kWakeReasonStringDisconnect);
    return;
  }
  uint32_t wake_pattern_index;
  if (triggers->GetU32AttributeValue(NL80211_WOWLAN_TRIG_PKT_PATTERN,
                                     &wake_pattern_index)) {
    SLOG(this, 3) << __func__ << ": "
                  << "Wakeup reason: Pattern " << wake_pattern_index;
    last_wake_reason_ = kWakeTriggerPattern;
    record_wake_reason_callback_.Run(kWakeReasonStringPattern);
    return;
  }
  AttributeListConstRefPtr results_list;
  if (triggers->ConstGetNestedAttributeList(
          NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS, &results_list)) {
    // It is possible that NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS is present
    // along with another wake trigger attribute. What this means is that the
    // firmware has detected a network, but the platform did not actually wake
    // on the detection of that network. In these cases, we will not parse the
    // net detect results; we return after parsing and reporting the actual
    // wakeup reason above.
    SLOG(this, 3) << __func__ << ": "
                  << "Wakeup reason: SSID";
    last_wake_reason_ = kWakeTriggerSSID;
    record_wake_reason_callback_.Run(kWakeReasonStringSSID);
    last_ssid_match_freqs_ = ParseWakeOnSSIDResults(results_list);
    return;
  }
  SLOG(this, 3) << __func__ << ": "
                << "Wakeup reason: Not supported";
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::OnBeforeSuspend(
    bool is_connected,
    const vector<ByteString>& ssid_whitelist,
    const ResultCallback& done_callback,
    const Closure& renew_dhcp_lease_callback,
    const Closure& remove_supplicant_networks_callback, bool have_dhcp_lease,
    uint32_t time_to_next_lease_renewal) {
  connected_before_suspend_ = is_connected;
#if defined(DISABLE_WAKE_ON_WIFI)
  // Wake on WiFi not supported, so immediately report success.
  done_callback.Run(Error(Error::kSuccess));
#else
  LOG(INFO) << __func__ << ": Wake on WiFi features enabled: "
            << wake_on_wifi_features_enabled_;
  suspend_actions_done_callback_ = done_callback;
  wake_on_ssid_whitelist_ = ssid_whitelist;
  dark_resume_history_.Clear();
  if (have_dhcp_lease && is_connected &&
      time_to_next_lease_renewal < kImmediateDHCPLeaseRenewalThresholdSeconds) {
    // Renew DHCP lease immediately if we have one that is expiring soon.
    renew_dhcp_lease_callback.Run();
    dispatcher_->PostTask(FROM_HERE, Bind(&WakeOnWiFi::BeforeSuspendActions,
                               weak_ptr_factory_.GetWeakPtr(), is_connected,
                               false, time_to_next_lease_renewal,
                               remove_supplicant_networks_callback));
  } else {
    dispatcher_->PostTask(FROM_HERE, Bind(&WakeOnWiFi::BeforeSuspendActions,
                               weak_ptr_factory_.GetWeakPtr(), is_connected,
                               have_dhcp_lease, time_to_next_lease_renewal,
                               remove_supplicant_networks_callback));
  }
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::OnAfterResume() {
#if !defined(DISABLE_WAKE_ON_WIFI)
  SLOG(this, 1) << __func__;
  wake_to_scan_timer_.Stop();
  dhcp_lease_renewal_timer_.Stop();
  if (WakeOnWiFiPacketEnabledAndSupported() ||
      WakeOnWiFiDarkConnectEnabledAndSupported()) {
    // Unconditionally disable wake on WiFi on resume if these features
    // were enabled before the last suspend.
    DisableWakeOnWiFi();
    metrics_->NotifySuspendWithWakeOnWiFiEnabledDone();
  }
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::OnDarkResume(
    bool is_connected,
    const vector<ByteString>& ssid_whitelist,
    const ResultCallback& done_callback,
    const Closure& renew_dhcp_lease_callback,
    const InitiateScanCallback& initiate_scan_callback,
    const Closure& remove_supplicant_networks_callback) {
#if defined(DISABLE_WAKE_ON_WIFI)
  done_callback.Run(Error(Error::kSuccess));
#else
  LOG(INFO) << __func__ << ": "
            << "Wake reason " << last_wake_reason_;
  metrics_->NotifyWakeOnWiFiOnDarkResume(last_wake_reason_);
  dark_resume_scan_retries_left_ = 0;
  suspend_actions_done_callback_ = done_callback;
  wake_on_ssid_whitelist_ = ssid_whitelist;

  if (last_wake_reason_ == kWakeTriggerSSID ||
      last_wake_reason_ == kWakeTriggerDisconnect ||
      (last_wake_reason_ == kWakeTriggerUnsupported && !is_connected)) {
    // We want to disable wake on WiFi in two specific cases of thrashing:
    //   1) Repeatedly waking on SSID in the presence of an AP that the WiFi
    //      device cannot connect to
    //   2) Repeatedly waking on disconnect because of a an AP that repeatedly
    //      disconnects the WiFi device but allows it to reconnect immediately
    // Therefore, we only count dark resumes caused by either of these wake
    // reasons when deciding whether or not to throttle wake on WiFi.
    //
    // In case the WiFi driver does not support wake reason reporting, we use
    // the WiFi device's connection status on dark resume as a proxy for these
    // wake reasons (i.e. when we wake on either SSID or disconnect, we should
    // be disconnected). This is not reliable for wake on disconnect, as the
    // WiFi device will report that it is connected as it enters dark
    // resume (crbug.com/505072).
    dark_resume_history_.RecordEvent();
  }
  if (dark_resume_history_.CountEventsWithinInterval(
          kDarkResumeFrequencySamplingPeriodShortMinutes * 60,
          EventHistory::kClockTypeBoottime) >= kMaxDarkResumesPerPeriodShort ||
      dark_resume_history_.CountEventsWithinInterval(
          kDarkResumeFrequencySamplingPeriodLongMinutes * 60,
          EventHistory::kClockTypeBoottime) >= kMaxDarkResumesPerPeriodLong) {
    LOG(ERROR) << __func__ << ": "
               << "Too many dark resumes; disabling wake on WiFi temporarily";
    // If too many dark resumes have triggered recently, we are probably
    // thrashing. Stop this by disabling wake on WiFi on the NIC, and
    // starting the wake to scan timer so that normal wake on WiFi behavior
    // resumes only |wake_to_scan_period_seconds_| later.
    dhcp_lease_renewal_timer_.Stop();
    wake_to_scan_timer_.Start(
        FROM_HERE, base::TimeDelta::FromSeconds(wake_to_scan_period_seconds_),
        Bind(&WakeOnWiFi::OnTimerWakeDoNothing, base::Unretained(this)));
    DisableWakeOnWiFi();
    dark_resume_history_.Clear();
    metrics_->NotifyWakeOnWiFiThrottled();
    last_ssid_match_freqs_.clear();
    return;
  }

  switch (last_wake_reason_) {
    case kWakeTriggerPattern: {
      // Go back to suspend immediately since packet would have been delivered
      // to userspace upon waking in dark resume. Do not reset the lease renewal
      // timer since we are not getting a new lease.
      dispatcher_->PostTask(FROM_HERE, Bind(
          &WakeOnWiFi::BeforeSuspendActions, weak_ptr_factory_.GetWeakPtr(),
          is_connected, false, 0, remove_supplicant_networks_callback));
      break;
    }
    case kWakeTriggerSSID:
    case kWakeTriggerDisconnect: {
      remove_supplicant_networks_callback.Run();
      metrics_->NotifyDarkResumeInitiateScan();
      InitiateScanInDarkResume(initiate_scan_callback,
                               last_wake_reason_ == kWakeTriggerSSID
                                   ? last_ssid_match_freqs_
                                   : WiFi::FreqSet());
      break;
    }
    case kWakeTriggerUnsupported:
    default: {
      if (is_connected) {
        renew_dhcp_lease_callback.Run();
      } else {
        remove_supplicant_networks_callback.Run();
        metrics_->NotifyDarkResumeInitiateScan();
        InitiateScanInDarkResume(initiate_scan_callback, WiFi::FreqSet());
      }
    }
  }

  // Only set dark resume to true after checking if we need to disable wake on
  // WiFi since calling WakeOnWiFi::DisableWakeOnWiFi directly bypasses
  // WakeOnWiFi::BeforeSuspendActions where |in_dark_resume_| is set to false.
  in_dark_resume_ = true;
  // Assume that we are disconnected if we time out. Consequently, we do not
  // need to start a DHCP lease renewal timer.
  dark_resume_actions_timeout_callback_.Reset(
      Bind(&WakeOnWiFi::BeforeSuspendActions, weak_ptr_factory_.GetWeakPtr(),
           false, false, 0, remove_supplicant_networks_callback));
  dispatcher_->PostDelayedTask(FROM_HERE,
                               dark_resume_actions_timeout_callback_.callback(),
                               DarkResumeActionsTimeoutMilliseconds);
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::BeforeSuspendActions(
    bool is_connected,
    bool start_lease_renewal_timer,
    uint32_t time_to_next_lease_renewal,
    const Closure& remove_supplicant_networks_callback) {
  LOG(INFO) << __func__ << ": "
            << (is_connected ? "connected" : "not connected");
  // Note: No conditional compilation because all entry points to this functions
  // are already conditionally compiled based on DISABLE_WAKE_ON_WIFI.

  metrics_->NotifyBeforeSuspendActions(is_connected, in_dark_resume_);
  last_ssid_match_freqs_.clear();
  last_wake_reason_ = kWakeTriggerUnsupported;
  // Add relevant triggers to be programmed into the NIC.
  wake_on_wifi_triggers_.clear();
  if ((!wake_on_packet_connections_.Empty() ||
       !wake_on_packet_types_.empty()) &&
      WakeOnWiFiPacketEnabledAndSupported() && is_connected) {
    SLOG(this, 3) << __func__ << ": "
                  << "Enabling wake on pattern";
    wake_on_wifi_triggers_.insert(kWakeTriggerPattern);
  }
  if (WakeOnWiFiDarkConnectEnabledAndSupported()) {
    if (is_connected) {
      SLOG(this, 3) << __func__ << ": "
                    << "Enabling wake on disconnect";
      wake_on_wifi_triggers_.insert(kWakeTriggerDisconnect);
      wake_on_wifi_triggers_.erase(kWakeTriggerSSID);
      wake_to_scan_timer_.Stop();
      if (start_lease_renewal_timer) {
        // Timer callback is NO-OP since dark resume logic (the
        // kWakeTriggerUnsupported case) will initiate DHCP lease renewal.
        dhcp_lease_renewal_timer_.Start(
            FROM_HERE, base::TimeDelta::FromSeconds(time_to_next_lease_renewal),
            Bind(&WakeOnWiFi::OnTimerWakeDoNothing, base::Unretained(this)));
      }
    } else {
      // Force a disconnect in case supplicant is currently in the process of
      // connecting, and remove all networks so scans triggered in dark resume
      // are passive.
      remove_supplicant_networks_callback.Run();
      dhcp_lease_renewal_timer_.Stop();
      wake_on_wifi_triggers_.erase(kWakeTriggerDisconnect);
      if (!wake_on_ssid_whitelist_.empty()) {
        SLOG(this, 3) << __func__ << ": "
                      << "Enabling wake on SSID";
        wake_on_wifi_triggers_.insert(kWakeTriggerSSID);
      }
      int num_extra_ssids =
          wake_on_ssid_whitelist_.size() - wake_on_wifi_max_ssids_;
      if (num_extra_ssids > 0 || force_wake_to_scan_timer_) {
        SLOG(this, 3) << __func__ << ": "
                      << "Starting wake to scan timer - "
                      << (num_extra_ssids > 0 ? "extra SSIDs" : "forced");
        if (num_extra_ssids > 0) {
          SLOG(this, 3) << __func__ << ": " << num_extra_ssids
                        << " extra SSIDs.";
        }
        // Start wake to scan timer in case the only SSIDs available for
        // auto-connect during suspend are the ones that we do not program our
        // NIC to wake on.
        // Timer callback is NO-OP since dark resume logic (the
        // kWakeTriggerUnsupported case) will initiate a passive scan.
        wake_to_scan_timer_.Start(
            FROM_HERE,
            base::TimeDelta::FromSeconds(wake_to_scan_period_seconds_),
            Bind(&WakeOnWiFi::OnTimerWakeDoNothing, base::Unretained(this)));
        // Trim SSID list to the max size that the NIC supports.
        wake_on_ssid_whitelist_.resize(wake_on_wifi_max_ssids_);
      }
    }
  }

  // Only call Cancel() here since it deallocates the underlying callback that
  // |remove_supplicant_networks_callback| references, which is invoked above.
  dark_resume_actions_timeout_callback_.Cancel();

  if (!in_dark_resume_ && wake_on_wifi_triggers_.empty()) {
    // No need program NIC on normal resume in this case since wake on WiFi
    // would already have been disabled on the last (non-dark) resume.
    SLOG(this, 1) << "No need to disable wake on WiFi on NIC in regular "
                     "suspend";
    RunAndResetSuspendActionsDoneCallback(Error(Error::kSuccess));
    return;
  }

  in_dark_resume_ = false;
  ApplyWakeOnWiFiSettings();
}

// static
WiFi::FreqSet WakeOnWiFi::ParseWakeOnSSIDResults(
    AttributeListConstRefPtr results_list) {
  WiFi::FreqSet freqs;
  AttributeIdIterator results_iter(*results_list);
  if (results_iter.AtEnd()) {
    SLOG(WiFi, nullptr, 3) << __func__ << ": "
                           << "Wake on SSID results not available";
    return freqs;
  }
  AttributeListConstRefPtr result;
  int ssid_num = 0;
  for (; !results_iter.AtEnd(); results_iter.Advance()) {
    if (!results_list->ConstGetNestedAttributeList(results_iter.GetId(),
                                                   &result)) {
      LOG(ERROR) << __func__ << ": "
                 << "Could not get result #" << results_iter.GetId()
                 << " in ssid_results";
      return freqs;
    }
    ByteString ssid_bytestring;
    if (!result->GetRawAttributeValue(NL80211_ATTR_SSID, &ssid_bytestring)) {
      // We assume that the SSID attribute must be present in each result.
      LOG(ERROR) << __func__ << ": "
                 << "No SSID available for result #" << results_iter.GetId();
      continue;
    }
    SLOG(WiFi, nullptr, 3) << "SSID " << ssid_num << ": "
                           << std::string(ssid_bytestring.GetConstData(),
                                          ssid_bytestring.GetConstData() +
                                              ssid_bytestring.GetLength());
    AttributeListConstRefPtr frequencies;
    uint32_t freq_value;
    if (result->ConstGetNestedAttributeList(NL80211_ATTR_SCAN_FREQUENCIES,
                                            &frequencies)) {
      AttributeIdIterator freq_iter(*frequencies);
      for (; !freq_iter.AtEnd(); freq_iter.Advance()) {
        if (frequencies->GetU32AttributeValue(freq_iter.GetId(), &freq_value)) {
          freqs.insert(freq_value);
          SLOG(WiFi, nullptr, 7) << "Frequency: " << freq_value;
        }
      }
    } else {
      SLOG(WiFi, nullptr, 3) << __func__ << ": "
                             << "No frequencies available for result #"
                             << results_iter.GetId();
    }
    ++ssid_num;
  }
  return freqs;
}

void WakeOnWiFi::InitiateScanInDarkResume(
    const InitiateScanCallback& initiate_scan_callback,
    const WiFi::FreqSet& freqs) {
  SLOG(this, 3) << __func__;
  if (!freqs.empty() && freqs.size() <= kMaxFreqsForDarkResumeScanRetries) {
    SLOG(this, 3) << __func__ << ": "
                  << "Allowing up to " << kMaxDarkResumeScanRetries
                  << " retries for passive scan on " << freqs.size()
                  << " frequencies";
    dark_resume_scan_retries_left_ = kMaxDarkResumeScanRetries;
  }
  initiate_scan_callback.Run(freqs);
}

void WakeOnWiFi::OnConnectedAndReachable(bool start_lease_renewal_timer,
                                         uint32_t time_to_next_lease_renewal) {
  SLOG(this, 3) << __func__;
  if (in_dark_resume_) {
#if defined(DISABLE_WAKE_ON_WIFI)
    SLOG(this, 3) << "Wake on WiFi not supported, so do nothing";
#else
    // If we obtain a DHCP lease, we are connected, so the callback to have
    // supplicant remove networks will not be invoked in
    // WakeOnWiFi::BeforeSuspendActions.
    BeforeSuspendActions(true, start_lease_renewal_timer,
                         time_to_next_lease_renewal, base::Closure());
#endif  // DISABLE_WAKE_ON_WIFI
  } else {
    SLOG(this, 3) << "Not in dark resume, so do nothing";
  }
}

void WakeOnWiFi::ReportConnectedToServiceAfterWake(bool is_connected,
        int seconds_in_suspend) {
    Metrics::WiFiConnectionStatusAfterWake status;
#if defined(DISABLE_WAKE_ON_WIFI)
      status = is_connected
          ? Metrics::kWiFiConnectionStatusAfterWakeWoWOffConnected
          : Metrics::kWiFiConnectionStatusAfterWakeWoWOffDisconnected;
#else
  if (WakeOnWiFiDarkConnectEnabledAndSupported()) {
    // Only logged if wake on WiFi is supported and wake on SSID was enabled to
    // maintain connectivity while suspended.
    status =
        is_connected
            ? Metrics::kWiFiConnectionStatusAfterWakeWoWOnConnected
            : Metrics::kWiFiConnectionStatusAfterWakeWoWOnDisconnected;
  } else {
    status =
        is_connected
            ? Metrics::kWiFiConnectionStatusAfterWakeWoWOffConnected
            : Metrics::kWiFiConnectionStatusAfterWakeWoWOffDisconnected;
  }
#endif  // DISABLE_WAKE_ON_WIFI
    metrics_->NotifyConnectedToServiceAfterWake(status);

    // Only log time spent in suspended state for each
    // connection status if wifi was connected before suspending
    if (connected_before_suspend_) {
      LOG(INFO) << "NotifySuspendDurationAfterWake: "
                << "status: " << status
                << "seconds_in_suspend: " << seconds_in_suspend;
      metrics_->NotifySuspendDurationAfterWake(status, seconds_in_suspend);
    }
}

void WakeOnWiFi::OnNoAutoConnectableServicesAfterScan(
    const vector<ByteString>& ssid_whitelist,
    const Closure& remove_supplicant_networks_callback,
    const InitiateScanCallback& initiate_scan_callback) {
#if !defined(DISABLE_WAKE_ON_WIFI)
  SLOG(this, 3) << __func__ << ": "
                << (in_dark_resume_ ? "In dark resume" : "Not in dark resume");
  if (!in_dark_resume_) {
    return;
  }
  if (dark_resume_scan_retries_left_) {
    --dark_resume_scan_retries_left_;
    SLOG(this, 3) << __func__ << ": "
                  << "Retrying dark resume scan ("
                  << dark_resume_scan_retries_left_ << " tries left)";
    metrics_->NotifyDarkResumeScanRetry();
    // Note: a scan triggered by supplicant in dark resume might cause a
    // retry, but we consider this acceptable.
    initiate_scan_callback.Run(last_ssid_match_freqs_);
  } else {
    wake_on_ssid_whitelist_ = ssid_whitelist;
    // Assume that if there are no services available for auto-connect, then we
    // cannot be connected. Therefore, no need for lease renewal parameters.
    BeforeSuspendActions(false, false, 0, remove_supplicant_networks_callback);
  }
#endif  // DISABLE_WAKE_ON_WIFI
}

void WakeOnWiFi::OnWiphyIndexReceived(uint32_t index) {
  wiphy_index_ = index;
  wiphy_index_received_ = true;
}

void WakeOnWiFi::OnScanStarted(bool is_active_scan) {
  if (!in_dark_resume_) {
    return;
  }
  if (last_wake_reason_ == kWakeTriggerUnsupported ||
      last_wake_reason_ == kWakeTriggerPattern) {
    // We don't expect active scans to be started when we wake on pattern or
    // RTC timers.
    if (is_active_scan) {
      LOG(ERROR) << "Unexpected active scan launched in dark resume";
    }
    metrics_->NotifyScanStartedInDarkResume(is_active_scan);
  }
}

}  // namespace shill
