wake_on_wifi.h revision 2b363903f38a515001c5edc7202403fcddb15a01
1d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan// Copyright 2014 The Chromium OS Authors. All rights reserved.
2d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan// Use of this source code is governed by a BSD-style license that can be
3d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan// found in the LICENSE file.
4d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan
5d6a8b519e3057f52313e502f502a4819a942e089Ben Chan#ifndef SHILL_WIFI_WAKE_ON_WIFI_H_
6d6a8b519e3057f52313e502f502a4819a942e089Ben Chan#define SHILL_WIFI_WAKE_ON_WIFI_H_
7d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan
83a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan#include <linux/if_ether.h>
93a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan#include <netinet/ip.h>
103a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan#include <netinet/ip6.h>
113a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan
125f4b175bca4a997f186010c177c44489c8ae95b4Samuel Tan#include <set>
13cb3ecf321c52de1e72cdf037a459cd893b7c51dbSamuel Tan#include <string>
143a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan#include <utility>
153a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan#include <vector>
163a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan
173a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan#include <base/cancelable_callback.h>
183a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan#include <gtest/gtest_prod.h>  // for FRIEND_TEST
193a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan#include <base/memory/ref_counted.h>
203a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan#include <base/memory/weak_ptr.h>
21787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan#include <components/timers/alarm_timer.h>
223a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan
233a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan#include "shill/callbacks.h"
243a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan#include "shill/ip_address_store.h"
25ff59a1896ea250b4450b54db697692e0b1949528Samuel Tan#include "shill/net/event_history.h"
268d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h"
2702e3dc3bc6e9fdb475bd13944f1c6764c921abbbPeter Qiu#include "shill/net/netlink_manager.h"
283a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan#include "shill/refptr_types.h"
295d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan#include "shill/wifi/wifi.h"
303a9c098afcd0456734092388d4aa7275716d33aaSamuel Tan
31d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tannamespace shill {
32d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan
33d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tanclass ByteString;
34d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tanclass Error;
353a1bf99b484ad8a9a054518f49046221251d5612Samuel Tanclass EventDispatcher;
363a9c098afcd0456734092388d4aa7275716d33aaSamuel Tanclass GetWakeOnPacketConnMessage;
3766bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tanclass Metrics;
383a9c098afcd0456734092388d4aa7275716d33aaSamuel Tanclass Nl80211Message;
3996e35cf43e6d5aa2378cdae6fea507e5335d12bbSamuel Tanclass PropertyStore;
40d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tanclass SetWakeOnPacketConnMessage;
413a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan
42c51454cb6a4442475449720549ac883731506909Samuel Tan// |WakeOnWiFi| performs all wake on WiFi related tasks and logic (e.g.
43c51454cb6a4442475449720549ac883731506909Samuel Tan// suspend/dark resume/resume logic, NIC wowlan programming via nl80211), and
44c51454cb6a4442475449720549ac883731506909Samuel Tan// stores the state necessary to perform these actions.
45c51454cb6a4442475449720549ac883731506909Samuel Tan//
46c51454cb6a4442475449720549ac883731506909Samuel Tan// One of the most significant roles of |WakeOnWiFi| is performing the correct
47c51454cb6a4442475449720549ac883731506909Samuel Tan// actions before suspend, during dark resume, and after resume in order to
48c51454cb6a4442475449720549ac883731506909Samuel Tan// maintain system connectivity (if the relevant wake on WiFi features  are
49c51454cb6a4442475449720549ac883731506909Samuel Tan// supported and enabled). The state machines determining which actions are
50c51454cb6a4442475449720549ac883731506909Samuel Tan// performed in these situations are described below:
51c51454cb6a4442475449720549ac883731506909Samuel Tan//
52c51454cb6a4442475449720549ac883731506909Samuel Tan// OnBeforeSuspend
53c51454cb6a4442475449720549ac883731506909Samuel Tan// ================
54c51454cb6a4442475449720549ac883731506909Samuel Tan// This function is run when Manager announces an upcoming system suspend.
55c51454cb6a4442475449720549ac883731506909Samuel Tan//
56c51454cb6a4442475449720549ac883731506909Samuel Tan//         +--------------+
57c51454cb6a4442475449720549ac883731506909Samuel Tan//         |          Yes |   +----------------+
58c51454cb6a4442475449720549ac883731506909Samuel Tan// +-------+--------+     +-->|Renew DHCP Lease|
59c51454cb6a4442475449720549ac883731506909Samuel Tan// |  Connected &   |         +------+---------+
60c51454cb6a4442475449720549ac883731506909Samuel Tan// |holding expiring|                |
61c51454cb6a4442475449720549ac883731506909Samuel Tan// |  DHCP lease?   |                v
62c51454cb6a4442475449720549ac883731506909Samuel Tan// +------+---------+         +--------------------+
63c51454cb6a4442475449720549ac883731506909Samuel Tan//        |               +-> |BeforeSuspendActions|
64c51454cb6a4442475449720549ac883731506909Samuel Tan//        |           No  |   +--------------------+
65c51454cb6a4442475449720549ac883731506909Samuel Tan//        +---------------+
66c51454cb6a4442475449720549ac883731506909Samuel Tan//
67c51454cb6a4442475449720549ac883731506909Samuel Tan// OnDarkResume
68c51454cb6a4442475449720549ac883731506909Samuel Tan// =============
69c51454cb6a4442475449720549ac883731506909Samuel Tan// This function is run when Manager announces that the system has entered
70c51454cb6a4442475449720549ac883731506909Samuel Tan// dark resume and that there is an upcoming system suspend.
71c51454cb6a4442475449720549ac883731506909Samuel Tan//
72c51454cb6a4442475449720549ac883731506909Samuel Tan// +-------------+      +------------+     Unsupported     +----------+
73c51454cb6a4442475449720549ac883731506909Samuel Tan// |  Too many   +----->|Wake reason?+-------------------->|Connected?|
74d1bec5d563afc9074a1875e2302d5ecf54c95f95Samuel Tan// |dark resumes?|  No  +-+----------+                     +-+-----+--+
75c51454cb6a4442475449720549ac883731506909Samuel Tan// +------+------+        |       |                          |     |
76c51454cb6a4442475449720549ac883731506909Samuel Tan//        | Yes           |       | Disconnect/           No |     | Yes
77c51454cb6a4442475449720549ac883731506909Samuel Tan//        v               |       |    SSID                  |     |
784c040c955b9fa793dbf871f1fd7b407f6e5c7ca0Samuel Tan// +-------------------+  |       v                          |     |
794c040c955b9fa793dbf871f1fd7b407f6e5c7ca0Samuel Tan// |  Disable Wake on  |  |     +------------+               |     v
804c040c955b9fa793dbf871f1fd7b407f6e5c7ca0Samuel Tan// |  WiFi, start wake |  |     |  Initiate  |<--------------+    +--------+
814c040c955b9fa793dbf871f1fd7b407f6e5c7ca0Samuel Tan// |  to scan timer &  |  |     |passive scan|                    |Get DHCP|
824c040c955b9fa793dbf871f1fd7b407f6e5c7ca0Samuel Tan// |  report readiness |  |     +-+----------+           +------->| Lease  |
834c040c955b9fa793dbf871f1fd7b407f6e5c7ca0Samuel Tan// +-------------------+  |       | ScanDone         Yes |        +--+---+-+
84c51454cb6a4442475449720549ac883731506909Samuel Tan//    +-------------------+       v                      |           |   |
85c51454cb6a4442475449720549ac883731506909Samuel Tan//    | Pattern                 +-------------+      +---------+     |   |
86c51454cb6a4442475449720549ac883731506909Samuel Tan//    |                    No   | Any services| Yes  |Connected|     |   |
87c51454cb6a4442475449720549ac883731506909Samuel Tan//    |    +--------------------+available for+----->| to AP?  |     |   |
88c51454cb6a4442475449720549ac883731506909Samuel Tan//    |    |                    | autoconnect?|      +---+-----+     |   |
89c51454cb6a4442475449720549ac883731506909Samuel Tan//    |    |                    +-------------+          |           |   |
90c51454cb6a4442475449720549ac883731506909Samuel Tan//    |    |                                             |No         |   |
91c51454cb6a4442475449720549ac883731506909Samuel Tan//    v    v                                             |           |   |
92c51454cb6a4442475449720549ac883731506909Samuel Tan// +--------------------+       +-------+                |           |   |
93c51454cb6a4442475449720549ac883731506909Samuel Tan// |BeforeSuspendActions|<------+Timeout|<---------------+       No  |   |
94c51454cb6a4442475449720549ac883731506909Samuel Tan// +--------------------+       +-------+<---------------------------+   |
95c51454cb6a4442475449720549ac883731506909Samuel Tan//         ^                                                             |
96c51454cb6a4442475449720549ac883731506909Samuel Tan//         |                   +-------------------+                     |
97c51454cb6a4442475449720549ac883731506909Samuel Tan//         +-------------------+ OnIPConfigUpdated/|             Yes     |
98c51454cb6a4442475449720549ac883731506909Samuel Tan//                             |OnIPv6ConfigUpdated|<--------------------+
99c51454cb6a4442475449720549ac883731506909Samuel Tan//                             +-------------------+
100c51454cb6a4442475449720549ac883731506909Samuel Tan//
101c51454cb6a4442475449720549ac883731506909Samuel Tan// BeforeSuspendActions
102c51454cb6a4442475449720549ac883731506909Samuel Tan// =====================
103c51454cb6a4442475449720549ac883731506909Samuel Tan// This function is run immediately before the system reports suspend readiness
104c51454cb6a4442475449720549ac883731506909Samuel Tan// to Manager. This is the common "exit path" taken by OnBeforeSuspend and
105c51454cb6a4442475449720549ac883731506909Samuel Tan// OnDarkResume before suspending.
106c51454cb6a4442475449720549ac883731506909Samuel Tan//
107c51454cb6a4442475449720549ac883731506909Samuel Tan//            Yes   +----------------------------+                   +---------+
108c51454cb6a4442475449720549ac883731506909Samuel Tan//          +-----> |Set Wake on Disconnect flag,+--+    +-------+   |Report   |
109c51454cb6a4442475449720549ac883731506909Samuel Tan//          |       |Start Lease Renewal Timer*  |  |    |Program|   |Suspend  |
110c51454cb6a4442475449720549ac883731506909Samuel Tan//          |       +----------------------------+  +--> |  NIC  |   |Readiness|
111c51454cb6a4442475449720549ac883731506909Samuel Tan// +--------+-+                                     |    +-+-----+   +---------+
112c51454cb6a4442475449720549ac883731506909Samuel Tan// |Connected?|                                     |      |   ^        ^
113c51454cb6a4442475449720549ac883731506909Samuel Tan// +--------+-+                                     |      |   |Failed  |
114c51454cb6a4442475449720549ac883731506909Samuel Tan//          |                                       |      v   |        |Success
115c51454cb6a4442475449720549ac883731506909Samuel Tan//          |       +----------------------------+  |  +-------+---+    |
116c51454cb6a4442475449720549ac883731506909Samuel Tan//          +-----> |Set Wake on SSID flag,      +--+  |  Verify   +----+
117c51454cb6a4442475449720549ac883731506909Samuel Tan//            No    |Start Wake To Scan Timer**  |     |Programming|
118c51454cb6a4442475449720549ac883731506909Samuel Tan//                  +----------------------------+     +-----------+
119c51454cb6a4442475449720549ac883731506909Samuel Tan//
120c51454cb6a4442475449720549ac883731506909Samuel Tan// *  if necessary (as indicated by caller of BeforeSuspendActions).
121c51454cb6a4442475449720549ac883731506909Samuel Tan// ** if we want to whitelist more SSIDs than our NIC supports.
122c51454cb6a4442475449720549ac883731506909Samuel Tan//
123c51454cb6a4442475449720549ac883731506909Samuel Tan// OnAfterResume
124c51454cb6a4442475449720549ac883731506909Samuel Tan// ==============
125c51454cb6a4442475449720549ac883731506909Samuel Tan// This is run after Manager announces that the system has fully resumed from
126c51454cb6a4442475449720549ac883731506909Samuel Tan// suspend.
127c51454cb6a4442475449720549ac883731506909Samuel Tan//
128c51454cb6a4442475449720549ac883731506909Samuel Tan// Wake on WiFi is disabled on the NIC if it was enabled before suspend or
129c51454cb6a4442475449720549ac883731506909Samuel Tan// dark resume, and both the wake to scan timer and DHCP lease renewal timers
130c51454cb6a4442475449720549ac883731506909Samuel Tan// are stopped.
131c51454cb6a4442475449720549ac883731506909Samuel Tan
1323a1bf99b484ad8a9a054518f49046221251d5612Samuel Tanclass WakeOnWiFi {
1333a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan public:
1342b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  typedef base::Callback<void(const WiFi::FreqSet&)> InitiateScanCallback;
1351897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // Callback used to report the wake reason for the current dark resume to
1361897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // powerd.
1372b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  typedef base::Callback<void(const std::string&)> RecordWakeReasonCallback;
1380932171ae1b59449130783c28ac54332d06d4e23Samuel Tan
1396d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // Types of triggers that we can program the NIC to wake the WiFi device.
1406d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  enum WakeOnWiFiTrigger {
1416d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan    kWakeTriggerUnsupported = 0,  // Used for reporting, not programming NIC.
1426d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan    kWakeTriggerPattern = 1,
1436d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan    kWakeTriggerDisconnect = 2,
1446d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan    kWakeTriggerSSID = 3
1456d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  };
1466d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan
1472b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  WakeOnWiFi(NetlinkManager* netlink_manager, EventDispatcher* dispatcher,
1482b363903f38a515001c5edc7202403fcddb15a01Paul Stewart             Metrics* metrics,
1491897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan             RecordWakeReasonCallback record_wake_reason_callback);
150fb02175e039a683cf9ac875ba0924858de6a08ffSamuel Tan  virtual ~WakeOnWiFi();
1513a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan
15296e35cf43e6d5aa2378cdae6fea507e5335d12bbSamuel Tan  // Registers |store| with properties related to wake on WiFi.
1532b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  void InitPropertyStore(PropertyStore* store);
15496e35cf43e6d5aa2378cdae6fea507e5335d12bbSamuel Tan
15566bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  // Starts |metrics_timer_| so that wake on WiFi related metrics are
15666bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  // periodically collected.
15766bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  void StartMetricsTimer();
15866bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan
1593a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Enable the NIC to wake on packets received from |ip_endpoint|.
1603a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Note: The actual programming of the NIC only happens before the system
1613a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // suspends, in |OnBeforeSuspend|.
1622b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  void AddWakeOnPacketConnection(const std::string& ip_endpoint, Error* error);
1633a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Remove rule to wake on packets received from |ip_endpoint| from the NIC.
1643a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Note: The actual programming of the NIC only happens before the system
1653a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // suspends, in |OnBeforeSuspend|.
1662b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  void RemoveWakeOnPacketConnection(const std::string& ip_endpoint,
1672b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                    Error* error);
1683a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Remove all rules to wake on incoming packets from the NIC.
1693a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Note: The actual programming of the NIC only happens before the system
1703a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // suspends, in |OnBeforeSuspend|.
1712b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  void RemoveAllWakeOnPacketConnections(Error* error);
1723a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Given a NL80211_CMD_NEW_WIPHY message |nl80211_message|, parses the
17396bdaecf58097e1cc54c5459e3c165de25c82134Samuel Tan  // wake on WiFi capabilities of the NIC and set relevant members of this
1743a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // WakeOnWiFi object to reflect the supported capbilities.
175235dcec779704b782f0608421d890fe6d183e7ccSamuel Tan  virtual void ParseWakeOnWiFiCapabilities(
1762b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const Nl80211Message& nl80211_message);
1770932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // Callback invoked when the system reports its wakeup reason.
1780932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //
1790932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // Arguments:
1800932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //  - |netlink_message|: wakeup report message (note: must manually check
1810932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //    this message to make sure it is a wakeup report message).
1820932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //
1830932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // Note: Assumes only one wakeup reason is received. If more than one is
1840932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // received, the only first one parsed will be handled.
1852b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  virtual void OnWakeupReasonReceived(const NetlinkMessage& netlink_message);
186c51454cb6a4442475449720549ac883731506909Samuel Tan  // Performs pre-suspend actions relevant to wake on WiFi functionality.
187787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //
188787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Arguments:
189787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |is_connected|: whether the WiFi device is connected.
190d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  //  - |ssid_whitelist|: list of SSIDs that the NIC will be programmed to wake
191d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  //    the system on if the NIC is programmed to wake on SSID.
192787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |done_callback|: callback to invoke when suspend  actions have
193787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    completed.
194787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |renew_dhcp_lease_callback|: callback to invoke to initiate DHCP lease
195787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    renewal.
196787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |remove_supplicant_networks_callback|: callback to invoke
197787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    to remove all networks from WPA supplicant.
198787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |have_dhcp_lease|: whether or not there is a DHCP lease to renew.
199787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |time_to_next_lease_renewal|: number of seconds until next DHCP lease
200787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    renewal is due.
201787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  virtual void OnBeforeSuspend(
202787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      bool is_connected,
2032b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::vector<ByteString>& ssid_whitelist,
2042b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const ResultCallback& done_callback,
2052b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const base::Closure& renew_dhcp_lease_callback,
2062b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const base::Closure& remove_supplicant_networks_callback,
207787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      bool have_dhcp_lease,
208787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      uint32_t time_to_next_lease_renewal);
2093a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Performs post-resume actions relevant to wake on wireless functionality.
210fb02175e039a683cf9ac875ba0924858de6a08ffSamuel Tan  virtual void OnAfterResume();
211787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Performs and post actions to be performed in dark resume.
212787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //
213787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Arguments:
214787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |is_connected|: whether the WiFi device is connected.
215d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  //  - |ssid_whitelist|: list of SSIDs that the NIC will be programmed to wake
216d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  //    the system on if the NIC is programmed to wake on SSID.
217787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |done_callback|: callback to invoke when dark resume actions have
218787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    completed.
219787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |renew_dhcp_lease_callback|: callback to invoke to initiate DHCP lease
220787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    renewal.
221787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |initate_scan_callback|: callback to invoke to initiate a scan.
222787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |remove_supplicant_networks_callback|: callback to invoke
223787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    to remove all networks from WPA supplicant.
224787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  virtual void OnDarkResume(
225787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      bool is_connected,
2262b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::vector<ByteString>& ssid_whitelist,
2272b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const ResultCallback& done_callback,
2282b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const base::Closure& renew_dhcp_lease_callback,
2292b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const InitiateScanCallback& initiate_scan_callback,
2302b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const base::Closure& remove_supplicant_networks_callback);
231787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Wrapper around WakeOnWiFi::BeforeSuspendActions that checks if shill is
232787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // currently in dark resume before invoking the function.
233787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  virtual void OnDHCPLeaseObtained(bool start_lease_renewal_timer,
234787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan                                   uint32_t time_to_next_lease_renewal);
2351964b5de186ef06fa89a78b27c3a112686bc36f7Samuel Tan  // Callback invoked to report whether this WiFi device is connected to
2361964b5de186ef06fa89a78b27c3a112686bc36f7Samuel Tan  // a service after waking from suspend.
2371964b5de186ef06fa89a78b27c3a112686bc36f7Samuel Tan  virtual void ReportConnectedToServiceAfterWake(bool is_connected);
238402bf2959e8b2c68627a7b66203ec84760bf2e03Samuel Tan  // Called in WiFi::ScanDoneTask when there are no WiFi services available
2394b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // for auto-connect after a scan. |initiate_scan_callback| is used for dark
2404b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // resume scan retries.
241402bf2959e8b2c68627a7b66203ec84760bf2e03Samuel Tan  virtual void OnNoAutoConnectableServicesAfterScan(
2422b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::vector<ByteString>& ssid_whitelist,
2432b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const base::Closure& remove_supplicant_networks_callback,
2442b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const InitiateScanCallback& initiate_scan_callback);
245d1bec5d563afc9074a1875e2302d5ecf54c95f95Samuel Tan  // Called by WiFi when it is notified by the kernel that a scan has started.
246d1bec5d563afc9074a1875e2302d5ecf54c95f95Samuel Tan  // If |is_active_scan| is true, the scan is an active scan. Otherwise, the
247d1bec5d563afc9074a1875e2302d5ecf54c95f95Samuel Tan  // scan is a passive scan.
248d1bec5d563afc9074a1875e2302d5ecf54c95f95Samuel Tan  virtual void OnScanStarted(bool is_active_scan);
2493a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan
2500e0ac0de9ac592495f780d7c372ba1212d4d374cSamuel Tan  bool in_dark_resume() { return in_dark_resume_; }
2510e0ac0de9ac592495f780d7c372ba1212d4d374cSamuel Tan
252235dcec779704b782f0608421d890fe6d183e7ccSamuel Tan  virtual void OnWiphyIndexReceived(uint32_t index);
253235dcec779704b782f0608421d890fe6d183e7ccSamuel Tan
2543a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan private:
2553a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  friend class WakeOnWiFiTest;  // access to several members for tests
2563a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  friend class WiFiObjectTest;  // netlink_manager_
257e58fa86282bb07867793ba78e9ff1c56fdc2d2b3Samuel Tan  // Tests that need kWakeOnWiFiNotSupported.
258e58fa86282bb07867793ba78e9ff1c56fdc2d2b3Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
259e58fa86282bb07867793ba78e9ff1c56fdc2d2b3Samuel Tan              WakeOnWiFiDisabled_SetWakeOnWiFiFeaturesEnabled);
260787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
261787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan              WakeOnWiFiDisabled_AddWakeOnPacketConnection_ReturnsError);
262787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
263787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan              WakeOnWiFiDisabled_RemoveWakeOnPacketConnection_ReturnsError);
264787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
265787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan              WakeOnWiFiDisabled_RemoveAllWakeOnPacketConnections_ReturnsError);
266fb02175e039a683cf9ac875ba0924858de6a08ffSamuel Tan  // Tests that need kMaxSetWakeOnPacketRetries.
267787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
2683a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan              RetrySetWakeOnPacketConnections_LessThanMaxRetries);
269787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
2703a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan              RetrySetWakeOnPacketConnections_MaxAttemptsWithCallbackSet);
271787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
2723a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan              RetrySetWakeOnPacketConnections_MaxAttemptsCallbackUnset);
273787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Tests that need WakeOnWiFi::kDarkResumeActionsTimeoutMilliseconds
274787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
275787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan              OnBeforeSuspend_DHCPLeaseRenewal);
2761897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // Tests that need dark resume wake reason strings
2771897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // (e.g. WakeOnWiFi::kWakeReasonStringDisconnect)
2781897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher,
2791897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan              OnWakeupReasonReceived_Disconnect);
2801897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher, OnWakeupReasonReceived_SSID);
2811897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  FRIEND_TEST(WakeOnWiFiTestWithMockDispatcher, OnWakeupReasonReceived_Pattern);
282bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  // Tests that need WakeOnWiFi::kMaxDarkResumesPerPeriodShort
283ff59a1896ea250b4450b54db697692e0b1949528Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithDispatcher, OnBeforeSuspend_ClearsEventHistory);
284bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  FRIEND_TEST(WakeOnWiFiTestWithDispatcher,
285bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan              OnDarkResume_NotConnected_MaxDarkResumes_ShortPeriod);
286bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  // Tests that need WakeOnWiFi::kMaxDarkResumesPerPeriodLong
287bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  FRIEND_TEST(WakeOnWiFiTestWithDispatcher,
288bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan              OnDarkResume_NotConnected_MaxDarkResumes_LongPeriod);
2894b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // kMaxFreqsForDarkResumeScanRetries, kMaxDarkResumeScanRetries
2904b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  FRIEND_TEST(WakeOnWiFiTestWithDispatcher, InitiateScanInDarkResume);
2913a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan
292fb02175e039a683cf9ac875ba0924858de6a08ffSamuel Tan  static const char kWakeOnIPAddressPatternsNotSupported[];
293e58fa86282bb07867793ba78e9ff1c56fdc2d2b3Samuel Tan  static const char kWakeOnWiFiNotSupported[];
294f8c0b3bcc1b9e918400c1fe76a9f6991bc32b55bSamuel Tan  static const int kVerifyWakeOnWiFiSettingsDelayMilliseconds;
2953a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  static const int kMaxSetWakeOnPacketRetries;
29666bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  static const int kMetricsReportingFrequencySeconds;
2975768ad4f08851b73eddb3328794eaa0ab3094bd3Samuel Tan  static const uint32_t kDefaultWakeToScanPeriodSeconds;
2987804df459a7f29a7463dbd7f0e8e2fea93ee766dSamuel Tan  static const uint32_t kDefaultNetDetectScanPeriodSeconds;
299787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  static const uint32_t kImmediateDHCPLeaseRenewalThresholdSeconds;
300bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  static const int kDarkResumeFrequencySamplingPeriodShortMinutes;
301bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  static const int kDarkResumeFrequencySamplingPeriodLongMinutes;
302bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  static const int kMaxDarkResumesPerPeriodShort;
303bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  static const int kMaxDarkResumesPerPeriodLong;
304787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  static int64_t DarkResumeActionsTimeoutMilliseconds;  // non-const for testing
3054b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  static const int kMaxFreqsForDarkResumeScanRetries;
3064b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  static const int kMaxDarkResumeScanRetries;
3071897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // Dark resume wake reason names. These will be sent to powerd via
3081897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // RecordDarkResumeWakeReason, to tell it the reason the system woke in the
3091897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // current dark resume.
3101897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  static const char kWakeReasonStringPattern[];
3111897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  static const char kWakeReasonStringDisconnect[];
3121897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  static const char kWakeReasonStringSSID[];
3133a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan
3142b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  std::string GetWakeOnWiFiFeaturesEnabled(Error* error);
3152b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  bool SetWakeOnWiFiFeaturesEnabled(const std::string& enabled, Error* error);
316740ee07e13d98ee9e0535ffea391326c8da13499Samuel Tan  // Helper function to run and reset |suspend_actions_done_callback_|.
3172b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  void RunAndResetSuspendActionsDoneCallback(const Error& error);
3183a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Used for comparison of ByteString pairs in a set.
3193a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  static bool ByteStringPairIsLessThan(
3202b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::pair<ByteString, ByteString>& lhs,
3212b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::pair<ByteString, ByteString>& rhs);
3223a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Creates a mask which specifies which bytes in pattern of length
3233a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // |pattern_len| to match against. Bits |offset| to |pattern_len| - 1 are set,
3243a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // which bits 0 to bits 0 to |offset| - 1 are unset. This mask is saved in
3253a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // |mask|.
3262b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static void SetMask(ByteString* mask, uint32_t pattern_len, uint32_t offset);
3273a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Creates a pattern and mask for a NL80211 message that programs the NIC to
3283a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // wake on packets originating from IP address |ip_addr|. The pattern and mask
3293a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // are saved in |pattern| and |mask| respectively. Returns true iff the
3303a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // pattern and mask are successfully created and written to |pattern| and
3313a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // |mask| respectively.
3322b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static bool CreateIPAddressPatternAndMask(const IPAddress& ip_addr,
3332b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                            ByteString* pattern,
3342b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                            ByteString* mask);
3352b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static void CreateIPV4PatternAndMask(const IPAddress& ip_addr,
3362b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                       ByteString* pattern, ByteString* mask);
3372b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static void CreateIPV6PatternAndMask(const IPAddress& ip_addr,
3382b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                       ByteString* pattern, ByteString* mask);
3393a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Creates and sets an attribute in a NL80211 message |msg| which indicates
3403a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // the index of the wiphy interface to program. Returns true iff |msg| is
3413a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // successfully configured.
3422b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static bool ConfigureWiphyIndex(Nl80211Message* msg, int32_t index);
3433a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Creates and sets attributes in an SetWakeOnPacketConnMessage |msg| so that
3443a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // the message will disable wake-on-packet functionality of the NIC with wiphy
3453a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // index |wiphy_index|. Returns true iff |msg| is successfully configured.
3463a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NOTE: Assumes that |msg| has not been altered since construction.
3472b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static bool ConfigureDisableWakeOnWiFiMessage(SetWakeOnPacketConnMessage* msg,
3483a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan                                                uint32_t wiphy_index,
3492b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                                Error* error);
3503a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Creates and sets attributes in a SetWakeOnPacketConnMessage |msg|
3513a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // so that the message will program the NIC with wiphy index |wiphy_index|
3523a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // with wake on wireless triggers in |trigs|. If |trigs| contains the
3536d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // kWakeTriggerPattern trigger, the message is configured to program the NIC
3546d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // to wake on packets from the IP addresses in |addrs|. If |trigs| contains
3556d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // the kSSID trigger, the message is configured to program the NIC to wake on
3566d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // the SSIDs in |ssid_whitelist|.
357d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // Returns true iff |msg| is successfully configured.
3583a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NOTE: Assumes that |msg| has not been altered since construction.
3593a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  static bool ConfigureSetWakeOnWiFiSettingsMessage(
3602b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      SetWakeOnPacketConnMessage* msg, const std::set<WakeOnWiFiTrigger>& trigs,
3612b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const IPAddressStore& addrs, uint32_t wiphy_index,
362d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan      uint32_t net_detect_scan_period_seconds,
3632b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::vector<ByteString>& ssid_whitelist,
3642b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      Error* error);
3653a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Helper function to ConfigureSetWakeOnWiFiSettingsMessage that creates a
3663a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // single nested attribute inside the attribute list referenced by |patterns|
3673a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // representing a wake-on-packet pattern matching rule with index |patnum|.
3683a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Returns true iff the attribute is successfully created and set.
3693a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NOTE: |patterns| is assumed to reference the nested attribute list
3703a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NL80211_WOWLAN_TRIG_PKT_PATTERN.
3713a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NOTE: |patnum| should be unique across multiple calls to this function to
3723a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // prevent the formation of a erroneous nl80211 message or the overwriting of
3733a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // pattern matching rules.
3742b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  static bool CreateSinglePattern(const IPAddress& ip_addr,
3753a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan                                  AttributeListRefPtr patterns, uint8_t patnum,
3762b363903f38a515001c5edc7202403fcddb15a01Paul Stewart                                  Error* error);
3773a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Creates and sets attributes in an GetWakeOnPacketConnMessage msg| so that
3783a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // the message will request for wake-on-packet settings information from the
3793a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NIC with wiphy index |wiphy_index|. Returns true iff |msg| is successfully
3803a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // configured.
3813a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NOTE: Assumes that |msg| has not been altered since construction.
3823a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  static bool ConfigureGetWakeOnWiFiSettingsMessage(
3832b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      GetWakeOnPacketConnMessage* msg, uint32_t wiphy_index, Error* error);
3843a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Given a NL80211_CMD_GET_WOWLAN response or NL80211_CMD_SET_WOWLAN request
3853a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // |msg|, returns true iff the wake-on-wifi trigger settings in |msg| match
386d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // those in |trigs|. Performs the following checks for the following triggers:
3876d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // - kWakeTriggerDisconnect: checks that the wake on disconnect flag is
3886d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  //   present and set.
389d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // - kIPAddress: checks that source IP addresses in |msg| match those reported
390d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  //   in |addrs|.
391d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // - kSSID: checks that the SSIDs in |ssid_whitelist| and the scan interval
392d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  //   |net_detect_scan_period_seconds| match those reported in |msg|.
393d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // Note: finding a trigger is in |msg| that is not expected based on the flags
394d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // in |trig| also counts as a mismatch.
395d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  static bool WakeOnWiFiSettingsMatch(
3962b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const Nl80211Message& msg, const std::set<WakeOnWiFiTrigger>& trigs,
3972b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const IPAddressStore& addrs, uint32_t net_detect_scan_period_seconds,
3982b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const std::vector<ByteString>& ssid_whitelist);
399742866741cd8902bfabd3d9731ccc6b4d5052de6Samuel Tan  // Handler for NL80211 message error responses from NIC wake on WiFi setting
400742866741cd8902bfabd3d9731ccc6b4d5052de6Samuel Tan  // programming attempts.
401742866741cd8902bfabd3d9731ccc6b4d5052de6Samuel Tan  void OnWakeOnWiFiSettingsErrorResponse(
402742866741cd8902bfabd3d9731ccc6b4d5052de6Samuel Tan      NetlinkManager::AuxilliaryMessageType type,
4032b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const NetlinkMessage* raw_message);
4043a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Message handler for NL80211_CMD_SET_WOWLAN responses.
4053a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  static void OnSetWakeOnPacketConnectionResponse(
4062b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const Nl80211Message& nl80211_message);
4073a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Request wake on WiFi settings for this WiFi device.
4083a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  void RequestWakeOnPacketSettings();
4093a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Verify that the wake on WiFi settings programmed into the NIC match
410d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // those recorded locally for this device in |wake_on_packet_connections_|,
411d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // |wake_on_wifi_triggers_|, and |wake_on_ssid_whitelist_|.
4122b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  void VerifyWakeOnWiFiSettings(const Nl80211Message& nl80211_message);
4133a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Sends an NL80211 message to program the NIC with wake on WiFi settings
414d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // configured in |wake_on_packet_connections_|, |wake_on_ssid_whitelist_|, and
415d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // |wake_on_wifi_triggers_|. If |wake_on_wifi_triggers_| is empty, calls
416d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // WakeOnWiFi::DisableWakeOnWiFi.
4173a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  void ApplyWakeOnWiFiSettings();
4183a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Helper function called by |ApplyWakeOnWiFiSettings| that sends an NL80211
4193a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // message to program the NIC to disable wake on WiFi.
4203a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  void DisableWakeOnWiFi();
4213a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Calls |ApplyWakeOnWiFiSettings| and counts this call as
4223a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // a retry. If |kMaxSetWakeOnPacketRetries| retries have already been
4233a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // performed, resets counter and returns.
4243a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  void RetrySetWakeOnPacketConnections();
425cb3ecf321c52de1e72cdf037a459cd893b7c51dbSamuel Tan  // Utility functions to check which wake on WiFi features are currently
426787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // enabled based on the descriptor |wake_on_wifi_features_enabled_| and
427787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // are supported by the NIC.
428787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  bool WakeOnPacketEnabledAndSupported();
429787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  bool WakeOnSSIDEnabledAndSupported();
43066bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  // Called by metrics_timer_ to reports metrics.
43166bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  void ReportMetrics();
432787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Actions executed before normal suspend and dark resume suspend.
433787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //
434787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Arguments:
435787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |is_connected|: whether the WiFi device is connected.
436787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |start_lease_renewal_timer|: whether or not to start the DHCP lease
437787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    renewal timer.
438787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |time_to_next_lease_renewal|: number of seconds until next DHCP lease
439787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    renewal is due.
440787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //  - |remove_supplicant_networks_callback|: callback to invoke
441787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  //    to remove all networks from WPA supplicant.
442787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  void BeforeSuspendActions(
443787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      bool is_connected,
444787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      bool start_lease_renewal_timer,
445787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan      uint32_t time_to_next_lease_renewal,
4462b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const base::Closure& remove_supplicant_networks_callback);
447787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan
448787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Needed for |dhcp_lease_renewal_timer_| and |wake_to_scan_timer_| since
449787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // passing a empty base::Closure() causes a run-time DCHECK error when
450787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // AlarmTimer::Start or AlarmTimer::Reset are called.
451787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  void OnTimerWakeDoNothing() {}
45266bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan
4530932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // Parses an attribute list containing the SSID matches that caused the
4540932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // system wake, along with the corresponding channels that these SSIDs were
4555d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan  // detected in. Returns a set of unique frequencies that the reported
4565d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan  // SSID matches occured in.
4570932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //
4580932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  // Arguments:
4590932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //  - |results_list|: Nested attribute list containing an array of nested
4600932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //    attributes which contain the NL80211_ATTR_SSID or
4610932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //    NL80211_ATTR_SCAN_FREQUENCIES attributes. This attribute list is assumed
4620932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //    to have been extracted from a NL80211_CMD_SET_WOWLAN response message
4630932171ae1b59449130783c28ac54332d06d4e23Samuel Tan  //    using the NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS id.
4645d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan  static WiFi::FreqSet ParseWakeOnWakeOnSSIDResults(
4650932171ae1b59449130783c28ac54332d06d4e23Samuel Tan      AttributeListConstRefPtr results_list);
4660932171ae1b59449130783c28ac54332d06d4e23Samuel Tan
4674b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // Sets the |dark_resume_scan_retries_left_| counter if necessary, then runs
4684b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // |initiate_scan_callback| with |freqs|.
4694b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  void InitiateScanInDarkResume(
4702b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const InitiateScanCallback& initiate_scan_callback,
4712b363903f38a515001c5edc7202403fcddb15a01Paul Stewart      const WiFi::FreqSet& freqs);
4724b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan
4733a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Pointers to objects owned by the WiFi object that created this object.
4742b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  EventDispatcher* dispatcher_;
4752b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  NetlinkManager* netlink_manager_;
4762b363903f38a515001c5edc7202403fcddb15a01Paul Stewart  Metrics* metrics_;
4773a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Executes after the NIC's wake-on-packet settings are configured via
4783a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // NL80211 messages to verify that the new configuration has taken effect.
4793a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Calls RequestWakeOnPacketSettings.
4803a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  base::CancelableClosure verify_wake_on_packet_settings_callback_;
481787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Callback to be invoked after all suspend actions finish executing both
482787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // before regular suspend and before suspend in dark resume.
4833a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  ResultCallback suspend_actions_done_callback_;
48466bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  // Callback to report wake on WiFi related metrics.
48566bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan  base::CancelableClosure report_metrics_callback_;
4863a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Number of retry attempts to program the NIC's wake-on-packet settings.
4873a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  int num_set_wake_on_packet_retries_;
4883a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Keeps track of triggers that the NIC will be programmed to wake from
4893a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // while suspended.
4903a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  std::set<WakeOnWiFi::WakeOnWiFiTrigger> wake_on_wifi_triggers_;
4913a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Keeps track of what wake on wifi triggers this WiFi device supports.
4923a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  std::set<WakeOnWiFi::WakeOnWiFiTrigger> wake_on_wifi_triggers_supported_;
493dda4da49919c0d10d84bf70ef4313837345cfb6cSamuel Tan  // Max number of patterns this WiFi device can be programmed to wake on at one
494dda4da49919c0d10d84bf70ef4313837345cfb6cSamuel Tan  // time.
4953a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  size_t wake_on_wifi_max_patterns_;
496dda4da49919c0d10d84bf70ef4313837345cfb6cSamuel Tan  // Max number of SSIDs this WiFi device can be programmed to wake on at one
497dda4da49919c0d10d84bf70ef4313837345cfb6cSamuel Tan  // time.
498dda4da49919c0d10d84bf70ef4313837345cfb6cSamuel Tan  uint32_t wake_on_wifi_max_ssids_;
4993a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  // Keeps track of IP addresses whose packets this device will wake upon
500d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // receiving while the device is suspended. Only used if the NIC is programmed
501d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // to wake on IP address patterns.
5023a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  IPAddressStore wake_on_packet_connections_;
503d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // Keeps track of SSIDs that this device will wake on the appearance of while
504d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // the device is suspended. Only used if the NIC is programmed to wake on
505d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  // SSIDs.
506d70ecdf36c94516b71cca8212caeb71da8c63d02Samuel Tan  std::vector<ByteString> wake_on_ssid_whitelist_;
5073a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  uint32_t wiphy_index_;
5083a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  bool wiphy_index_received_;
50996e35cf43e6d5aa2378cdae6fea507e5335d12bbSamuel Tan  // Describes the wake on WiFi features that are currently enabled.
51096e35cf43e6d5aa2378cdae6fea507e5335d12bbSamuel Tan  std::string wake_on_wifi_features_enabled_;
511787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Timer that wakes the system to renew DHCP leases.
512787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  timers::AlarmTimer dhcp_lease_renewal_timer_;
513787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Timer that wakes the system to scan for networks.
514787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  timers::AlarmTimer wake_to_scan_timer_;
515787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Executes when the dark resume actions timer expires. Calls
516787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // ScanTimerHandler.
517787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  base::CancelableClosure dark_resume_actions_timeout_callback_;
518787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  // Whether shill is currently in dark resume.
519787a1cebf2452c14bf392ab99902e686ea4a6fb4Samuel Tan  bool in_dark_resume_;
5205768ad4f08851b73eddb3328794eaa0ab3094bd3Samuel Tan  // Period (in seconds) between instances where the system wakes from suspend
5215768ad4f08851b73eddb3328794eaa0ab3094bd3Samuel Tan  // to scan for networks in dark resume.
5225768ad4f08851b73eddb3328794eaa0ab3094bd3Samuel Tan  uint32_t wake_to_scan_period_seconds_;
5237804df459a7f29a7463dbd7f0e8e2fea93ee766dSamuel Tan  // Period (in seconds) between instances where the NIC performs Net Detect
5247804df459a7f29a7463dbd7f0e8e2fea93ee766dSamuel Tan  // scans while the system is suspended.
5257804df459a7f29a7463dbd7f0e8e2fea93ee766dSamuel Tan  uint32_t net_detect_scan_period_seconds_;
526bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  // Timestamps of dark resume wakes that took place during the current
527bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  // or most recent suspend.
528bc78c1fefe3bd5d3e4397cb1b4b42cc78ad1e87eSamuel Tan  EventHistory dark_resume_history_;
5296d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  // Last wake reason reported by the kernel.
5306d61faf84ef5eb2545bc6eee8a4d74109dfdd6d1Samuel Tan  WakeOnWiFiTrigger last_wake_reason_;
531c49955996cfa8f28bf3c112499351be7870319b1Samuel Tan  // Whether or not to always start |wake_to_scan_timer_| before suspend.
532c49955996cfa8f28bf3c112499351be7870319b1Samuel Tan  bool force_wake_to_scan_timer_;
5335d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan  // Frequencies that the last wake on SSID matches reported by the kernel
5345d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan  // occurred in.
5355d0b8076eee13cd9b3de1c62f982ef0dc430260cSamuel Tan  WiFi::FreqSet last_ssid_match_freqs_;
5364b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // How many more times to retry the last dark resume scan that shill launched
5374b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  // if no auto-connectable services were found.
5384b8436a5136baa1716ca6a1013e2a4ad38ad2437Samuel Tan  int dark_resume_scan_retries_left_;
53966bddc67c71dd197211ca08c5a4835bd6cfa5ed2Samuel Tan
5401897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // Callback invoked to report the wake reason for the current dark resume to
5411897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  // powerd.
5421897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan  RecordWakeReasonCallback record_wake_reason_callback_;
5431897afaeb89003f5cc75a256f6fd7528e6abd54fSamuel Tan
5443a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  base::WeakPtrFactory<WakeOnWiFi> weak_ptr_factory_;
545d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan
5463a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan  DISALLOW_COPY_AND_ASSIGN(WakeOnWiFi);
5473a1bf99b484ad8a9a054518f49046221251d5612Samuel Tan};
548d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan
549d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan}  // namespace shill
550d03b95db5d05928ea63fc9f8aac5151e93c43a2fSamuel Tan
551d6a8b519e3057f52313e502f502a4819a942e089Ben Chan#endif  // SHILL_WIFI_WAKE_ON_WIFI_H_
552