wifi_provider.h revision f024ef470665bee08eeb9cdfe5bbcc3fd7bbc8fd
1// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_WIFI_PROVIDER_H_
6#define SHILL_WIFI_PROVIDER_H_
7
8#include <time.h>
9
10#include <deque>
11#include <map>
12
13#include <gtest/gtest_prod.h>  // for FRIEND_TEST
14
15#include "shill/accessor_interface.h"  // for ByteArrays
16#include "shill/provider_interface.h"
17#include "shill/refptr_types.h"
18
19namespace shill {
20
21class ControlInterface;
22class Error;
23class EventDispatcher;
24class KeyValueStore;
25class Manager;
26class Metrics;
27class StoreInterface;
28class Time;
29class WiFiEndpoint;
30class WiFiService;
31
32// The WiFi Provider is the holder of all WiFi Services.  It holds both
33// visible (created due to an Endpoint becoming visible) and invisible
34// (created due to user or storage configuration) Services.
35class WiFiProvider : public ProviderInterface {
36 public:
37  static const char kStorageFrequencies[];
38  static const int kMaxStorageFrequencies;
39  typedef std::map<uint16, int64> ConnectFrequencyMap;
40  // The key to |ConnectFrequencyMapDated| is the number of days since the
41  // Epoch.
42  typedef std::map<time_t, ConnectFrequencyMap> ConnectFrequencyMapDated;
43  struct FrequencyCount {
44    FrequencyCount() : frequency(0), connection_count(0) {}
45    FrequencyCount(uint16 freq, size_t conn)
46        : frequency(freq), connection_count(conn) {}
47    uint16 frequency;
48    size_t connection_count;  // Number of successful connections at this
49                              // frequency.
50  };
51  typedef std::deque<FrequencyCount> FrequencyCountList;
52
53  WiFiProvider(ControlInterface *control_interface,
54               EventDispatcher *dispatcher,
55               Metrics *metrics,
56               Manager *manager);
57  virtual ~WiFiProvider();
58
59  // Called by Manager as a part of the Provider interface.  The attributes
60  // used for matching services for the WiFi provider are the SSID, mode and
61  // security parameters.
62  virtual void CreateServicesFromProfile(const ProfileRefPtr &profile) override;
63  virtual ServiceRefPtr FindSimilarService(
64      const KeyValueStore &args, Error *error) const override;
65  virtual ServiceRefPtr GetService(const KeyValueStore &args,
66                                   Error *error) override;
67  virtual ServiceRefPtr CreateTemporaryService(
68      const KeyValueStore &args, Error *error) override;
69  virtual void Start() override;
70  virtual void Stop() override;
71
72  // Find a Service this Endpoint should be associated with.
73  virtual WiFiServiceRefPtr FindServiceForEndpoint(
74      const WiFiEndpointConstRefPtr &endpoint);
75
76  // Find or create a Service for |endpoint| to be associated with.  This
77  // method first calls FindServiceForEndpoint, and failing this, creates
78  // a new Service.  It then associates |endpoint| with this service.
79  virtual void OnEndpointAdded(const WiFiEndpointConstRefPtr &endpoint);
80
81  // Called by a Device when it removes an Endpoint.  If the Provider
82  // forgets a service as a result, it returns a reference to the
83  // forgotten service, otherwise it returns a null reference.
84  virtual WiFiServiceRefPtr OnEndpointRemoved(
85      const WiFiEndpointConstRefPtr &endpoint);
86
87  // Called by a Device when it receives notification that an Endpoint
88  // has changed.  Ensure the updated endpoint still matches its
89  // associated service.  If necessary re-assign the endpoint to a new
90  // service, otherwise notify the associated service of the update to
91  // the endpoint.
92  virtual void OnEndpointUpdated(const WiFiEndpointConstRefPtr &endpoint);
93
94  // Called by a WiFiService when it is unloaded and no longer visible.
95  virtual bool OnServiceUnloaded(const WiFiServiceRefPtr &service);
96
97  // Get the list of SSIDs for hidden WiFi services we are aware of.
98  virtual ByteArrays GetHiddenSSIDList();
99
100  // Calls WiFiService::FixupServiceEntries() and adds a UMA metric if
101  // this causes entries to be updated.
102  virtual void LoadAndFixupServiceEntries(StoreInterface *storage,
103                                          bool is_default_profile);
104
105  // Save configuration for wifi_provider to |storage|.
106  virtual bool Save(StoreInterface *storage) const;
107
108  virtual void IncrementConnectCount(uint16 frequency_mhz);
109
110  // Returns a list of all of the frequencies on which this device has
111  // connected.  This data is accumulated across multiple shill runs.
112  virtual FrequencyCountList GetScanFrequencies() const;
113
114 private:
115  friend class WiFiProviderTest;
116  FRIEND_TEST(WiFiProviderTest, FrequencyMapAgingIllegalDay);
117  FRIEND_TEST(WiFiProviderTest, FrequencyMapBasicAging);
118  FRIEND_TEST(WiFiProviderTest, FrequencyMapToStringList);
119  FRIEND_TEST(WiFiProviderTest, FrequencyMapToStringListEmpty);
120  FRIEND_TEST(WiFiProviderTest, IncrementConnectCount);
121  FRIEND_TEST(WiFiProviderTest, IncrementConnectCountCreateNew);
122  FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntries);
123  FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo);
124  FRIEND_TEST(WiFiProviderTest, StringListToFrequencyMap);
125  FRIEND_TEST(WiFiProviderTest, StringListToFrequencyMapEmpty);
126
127  typedef std::map<const WiFiEndpoint *, WiFiServiceRefPtr> EndpointServiceMap;
128
129  static const char kManagerErrorSSIDTooLong[];
130  static const char kManagerErrorSSIDTooShort[];
131  static const char kManagerErrorSSIDRequired[];
132  static const char kManagerErrorUnsupportedSecurityMode[];
133  static const char kManagerErrorUnsupportedServiceMode[];
134  static const char kFrequencyDelimiter;
135  static const char kStartWeekHeader[];
136  static const time_t kIllegalStartWeek;
137  static const char kStorageId[];
138  static const time_t kWeeksToKeepFrequencyCounts;
139  static const time_t kSecondsPerWeek;
140
141  // Add a service to the service_ vector and register it with the Manager.
142  WiFiServiceRefPtr AddService(const std::vector<uint8_t> &ssid,
143                               const std::string &mode,
144                               const std::string &security,
145                               bool is_hidden);
146
147  // Find a service given its properties.
148  WiFiServiceRefPtr FindService(const std::vector<uint8_t> &ssid,
149                                const std::string &mode,
150                                const std::string &security) const;
151
152  // Returns a WiFiServiceRefPtr for unit tests and for down-casting to a
153  // ServiceRefPtr in GetService().
154  WiFiServiceRefPtr GetWiFiService(const KeyValueStore &args, Error *error);
155
156  // Disassociate the service from its WiFi device and remove it from the
157  // services_ vector.
158  void ForgetService(const WiFiServiceRefPtr &service);
159
160  // Retrieve a WiFi service's identifying properties from passed-in |args|.
161  // Returns true if |args| are valid and populates |ssid|, |mode|,
162  // |security| and |hidden_ssid|, if successful.  Otherwise, this function
163  // returns false and populates |error| with the reason for failure.  It
164  // is a fatal error if the "Type" parameter passed in |args| is not kWiFi.
165  static bool GetServiceParametersFromArgs(const KeyValueStore &args,
166                                           std::vector<uint8_t> *ssid_bytes,
167                                           std::string *mode,
168                                           std::string *security_method,
169                                           bool *hidden_ssid,
170                                           Error *error);
171
172  // Converts frequency profile information from a list of strings of the form
173  // "frequency:connection_count" to a form consistent with
174  // |connect_count_by_frequency_|.  The first string must be of the form
175  // [nnn] where |nnn| is a positive integer that represents the creation time
176  // (number of days since the Epoch) of the data.
177  static time_t StringListToFrequencyMap(
178      const std::vector<std::string> &strings,
179      ConnectFrequencyMap *numbers);
180
181  // Extracts the start week from the first string in the StringList for
182  // |StringListToFrequencyMap|.
183  static time_t GetStringListStartWeek(const std::string &week_string);
184
185  // Extracts frequency and connection count from a string from the StringList
186  // for |StringListToFrequencyMap|.  Places those values in |numbers|.
187  static void ParseStringListFreqCount(const std::string &freq_count_string,
188                                       ConnectFrequencyMap *numbers);
189
190  // Converts frequency profile information from a form consistent with
191  // |connect_count_by_frequency_| to a list of strings of the form
192  // "frequency:connection_count".  The |creation_day| is the day that the
193  // data was first createed (represented as the number of days since the
194  // Epoch).
195  static void FrequencyMapToStringList(time_t creation_day,
196                                       const ConnectFrequencyMap &numbers,
197                                       std::vector<std::string> *strings);
198
199  ControlInterface *control_interface_;
200  EventDispatcher *dispatcher_;
201  Metrics *metrics_;
202  Manager *manager_;
203
204  std::vector<WiFiServiceRefPtr> services_;
205  EndpointServiceMap service_by_endpoint_;
206
207  bool running_;
208
209  // Map of frequencies at which we've connected and the number of times a
210  // successful connection has been made at that frequency.  Absent frequencies
211  // have not had a successful connection.
212  ConnectFrequencyMap connect_count_by_frequency_;
213  // A number of entries of |ConnectFrequencyMap| stored by date of creation.
214  ConnectFrequencyMapDated connect_count_by_frequency_dated_;
215
216  // Count of successful wifi connections we've made.
217  int64_t total_frequency_connections_;
218
219  Time *time_;
220
221  DISALLOW_COPY_AND_ASSIGN(WiFiProvider);
222};
223
224}  // namespace shill
225
226#endif  // SHILL_WIFI_PROVIDER_H_
227