// 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 <sys/timerfd.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(const WakeOnWiFi* w) {
  return "(wake_on_wifi)";
}
}  // namespace Logging

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& mac_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),
      mac_address_(mac_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_);
  dhcp_lease_renewal_timer_ = timers::SimpleAlarmTimer::Create();
  wake_to_scan_timer_ = timers::SimpleAlarmTimer::Create();
}

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& mac_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(mac_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& mac_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(mac_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& mac_address,
    uint32_t pattern_min_len,
    uint32_t net_detect_scan_period_seconds,
    const vector<ByteString>& allowed_ssids,
    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::Contains(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(mac_address, pattern_min_len,
                                                  packet_type, &pattern, &mask);
            if (!CreateSingleAttribute(pattern, mask, patterns, patnum++,
                                       error)) {
              return false;
            }
            CreatePacketTypePatternAndMaskforIPV6(mac_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 : allowed_ssids) {
          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& mac_address,
    uint32_t min_pattern_len,
    const vector<ByteString>& allowed_ssids) {
#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::Contains(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::Contains(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::Contains(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(mac_address, min_pattern_len,
                                                  packet_type, &temp_pattern,
                                                  &temp_mask);
            expected_patt_mask_pairs.emplace(temp_pattern, temp_mask);
            CreatePacketTypePatternAndMaskforIPV6(mac_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::Contains(
                  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(
            allowed_ssids.begin(), allowed_ssids.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::Contains(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::Contains(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::Contains(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::Contains(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::Contains(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::Contains(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::Contains(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_, mac_address_,
          min_pattern_len_, wake_on_allowed_ssids_)) {
    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_, mac_address_, min_pattern_len_,
          net_detect_scan_period_seconds_, wake_on_allowed_ssids_, &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::Contains(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::Contains(wake_on_wifi_triggers_supported_,
                      kWakeTriggerDisconnect) ||
      !base::Contains(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(
          mac_address_, min_pattern_len_, IPPROTO_TCP, &dummy_pattern,
          &dummy_mask);
      size_t ipv4_packet_type_pattern_len = dummy_pattern.GetLength();
      WakeOnWiFi::CreatePacketTypePatternAndMaskforIPV6(
          mac_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_
                    << " 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>& allowed_ssids,
    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_allowed_ssids_ = allowed_ssids;
  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>& allowed_ssids,
    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_allowed_ssids_ = allowed_ssids;

  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_allowed_ssids_.empty()) {
        SLOG(this, 3) << __func__ << ": "
                      << "Enabling wake on SSID";
        wake_on_wifi_triggers_.insert(kWakeTriggerSSID);
      }
      int num_extra_ssids =
          wake_on_allowed_ssids_.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_allowed_ssids_.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>& allowed_ssids,
    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_allowed_ssids_ = allowed_ssids;
    // 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
