blob: b712e6c26b3e7126a1606e9540025702359904e0 [file] [log] [blame]
Paul Stewart21f2aae2013-01-17 17:10:08 -08001// 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
Wade Guthrie60a37062013-04-02 11:39:09 -07005#ifndef SHILL_WIFI_PROVIDER_H_
6#define SHILL_WIFI_PROVIDER_H_
7
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07008#include <time.h>
9
Wade Guthriea60a11c2013-04-12 17:47:34 -070010#include <deque>
Wade Guthrie60a37062013-04-02 11:39:09 -070011#include <map>
12
13#include <gtest/gtest_prod.h> // for FRIEND_TEST
Paul Stewart21f2aae2013-01-17 17:10:08 -080014
Paul Stewart3c504012013-01-17 17:49:58 -080015#include "shill/accessor_interface.h" // for ByteArrays
Paul Stewartbc14fb72013-07-30 08:21:58 -070016#include "shill/provider_interface.h"
Paul Stewart21f2aae2013-01-17 17:10:08 -080017#include "shill/refptr_types.h"
18
19namespace shill {
20
21class ControlInterface;
22class Error;
23class EventDispatcher;
24class KeyValueStore;
25class Manager;
26class Metrics;
Paul Stewart3c504012013-01-17 17:49:58 -080027class StoreInterface;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070028class Time;
Paul Stewart21f2aae2013-01-17 17:10:08 -080029class 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.
Paul Stewartbc14fb72013-07-30 08:21:58 -070035class WiFiProvider : public ProviderInterface {
Paul Stewart21f2aae2013-01-17 17:10:08 -080036 public:
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070037 static const char kStorageFrequencies[];
38 static const int kMaxStorageFrequencies;
Wade Guthrie60a37062013-04-02 11:39:09 -070039 typedef std::map<uint16, int64> ConnectFrequencyMap;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070040 // The key to |ConnectFrequencyMapDated| is the number of days since the
41 // Epoch.
42 typedef std::map<time_t, ConnectFrequencyMap> ConnectFrequencyMapDated;
Wade Guthriea60a11c2013-04-12 17:47:34 -070043 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;
Wade Guthrie60a37062013-04-02 11:39:09 -070052
Paul Stewart21f2aae2013-01-17 17:10:08 -080053 WiFiProvider(ControlInterface *control_interface,
54 EventDispatcher *dispatcher,
55 Metrics *metrics,
56 Manager *manager);
57 virtual ~WiFiProvider();
58
Paul Stewart0e51ad92013-07-26 14:42:55 -070059 // 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;
Paul Stewart0e51ad92013-07-26 14:42:55 -070063 virtual ServiceRefPtr FindSimilarService(
64 const KeyValueStore &args, Error *error) const override;
Paul Stewartbc14fb72013-07-30 08:21:58 -070065 virtual ServiceRefPtr GetService(const KeyValueStore &args,
66 Error *error) override;
Paul Stewart0e51ad92013-07-26 14:42:55 -070067 virtual ServiceRefPtr CreateTemporaryService(
68 const KeyValueStore &args, Error *error) override;
69 virtual void Start() override;
70 virtual void Stop() override;
Paul Stewartd2e1c362013-03-03 19:06:07 -080071
Paul Stewart3c504012013-01-17 17:49:58 -080072 // 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
Paul Stewart0427cc12013-03-25 13:50:39 -070087 // 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
Paul Stewart3c504012013-01-17 17:49:58 -080094 // 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.
Wade Guthrie60a37062013-04-02 11:39:09 -0700102 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);
Paul Stewart21f2aae2013-01-17 17:10:08 -0800109
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -0700110 // 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
Paul Stewart21f2aae2013-01-17 17:10:08 -0800114 private:
115 friend class WiFiProviderTest;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700116 FRIEND_TEST(WiFiProviderTest, FrequencyMapAgingIllegalDay);
117 FRIEND_TEST(WiFiProviderTest, FrequencyMapBasicAging);
Wade Guthrie60a37062013-04-02 11:39:09 -0700118 FRIEND_TEST(WiFiProviderTest, FrequencyMapToStringList);
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700119 FRIEND_TEST(WiFiProviderTest, FrequencyMapToStringListEmpty);
120 FRIEND_TEST(WiFiProviderTest, IncrementConnectCount);
121 FRIEND_TEST(WiFiProviderTest, IncrementConnectCountCreateNew);
Wade Guthrie60a37062013-04-02 11:39:09 -0700122 FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntries);
123 FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo);
124 FRIEND_TEST(WiFiProviderTest, StringListToFrequencyMap);
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700125 FRIEND_TEST(WiFiProviderTest, StringListToFrequencyMapEmpty);
Paul Stewart21f2aae2013-01-17 17:10:08 -0800126
Paul Stewart0427cc12013-03-25 13:50:39 -0700127 typedef std::map<const WiFiEndpoint *, WiFiServiceRefPtr> EndpointServiceMap;
128
Paul Stewart3c504012013-01-17 17:49:58 -0800129 static const char kManagerErrorSSIDTooLong[];
130 static const char kManagerErrorSSIDTooShort[];
131 static const char kManagerErrorSSIDRequired[];
132 static const char kManagerErrorUnsupportedSecurityMode[];
133 static const char kManagerErrorUnsupportedServiceMode[];
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700134 static const char kFrequencyDelimiter;
135 static const char kStartWeekHeader[];
136 static const time_t kIllegalStartWeek;
Wade Guthrie60a37062013-04-02 11:39:09 -0700137 static const char kStorageId[];
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700138 static const time_t kWeeksToKeepFrequencyCounts;
139 static const time_t kSecondsPerWeek;
Paul Stewart3c504012013-01-17 17:49:58 -0800140
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
Paul Stewart0e51ad92013-07-26 14:42:55 -0700152 // 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
Paul Stewart3c504012013-01-17 17:49:58 -0800156 // Disassociate the service from its WiFi device and remove it from the
157 // services_ vector.
158 void ForgetService(const WiFiServiceRefPtr &service);
159
Paul Stewartd2e1c362013-03-03 19:06:07 -0800160 // 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
165 // flimflam::kWiFi.
166 static bool GetServiceParametersFromArgs(const KeyValueStore &args,
167 std::vector<uint8_t> *ssid_bytes,
168 std::string *mode,
169 std::string *security_method,
170 bool *hidden_ssid,
171 Error *error);
172
Wade Guthrie60a37062013-04-02 11:39:09 -0700173 // Converts frequency profile information from a list of strings of the form
Wade Guthriea60a11c2013-04-12 17:47:34 -0700174 // "frequency:connection_count" to a form consistent with
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700175 // |connect_count_by_frequency_|. The first string must be of the form
176 // [nnn] where |nnn| is a positive integer that represents the creation time
177 // (number of days since the Epoch) of the data.
178 static time_t StringListToFrequencyMap(
179 const std::vector<std::string> &strings,
180 ConnectFrequencyMap *numbers);
181
182 // Extracts the start week from the first string in the StringList for
183 // |StringListToFrequencyMap|.
184 static time_t GetStringListStartWeek(const std::string &week_string);
185
186 // Extracts frequency and connection count from a string from the StringList
187 // for |StringListToFrequencyMap|. Places those values in |numbers|.
188 static void ParseStringListFreqCount(const std::string &freq_count_string,
Wade Guthrie60a37062013-04-02 11:39:09 -0700189 ConnectFrequencyMap *numbers);
190
191 // Converts frequency profile information from a form consistent with
192 // |connect_count_by_frequency_| to a list of strings of the form
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700193 // "frequency:connection_count". The |creation_day| is the day that the
194 // data was first createed (represented as the number of days since the
195 // Epoch).
196 static void FrequencyMapToStringList(time_t creation_day,
197 const ConnectFrequencyMap &numbers,
Wade Guthrie60a37062013-04-02 11:39:09 -0700198 std::vector<std::string> *strings);
199
Paul Stewart21f2aae2013-01-17 17:10:08 -0800200 ControlInterface *control_interface_;
201 EventDispatcher *dispatcher_;
202 Metrics *metrics_;
203 Manager *manager_;
204
Paul Stewart3c504012013-01-17 17:49:58 -0800205 std::vector<WiFiServiceRefPtr> services_;
Paul Stewart0427cc12013-03-25 13:50:39 -0700206 EndpointServiceMap service_by_endpoint_;
207
Paul Stewart6c351ff2013-02-25 15:13:03 -0800208 bool running_;
Paul Stewart3c504012013-01-17 17:49:58 -0800209
Wade Guthrie60a37062013-04-02 11:39:09 -0700210 // Map of frequencies at which we've connected and the number of times a
211 // successful connection has been made at that frequency. Absent frequencies
212 // have not had a successful connection.
213 ConnectFrequencyMap connect_count_by_frequency_;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700214 // A number of entries of |ConnectFrequencyMap| stored by date of creation.
215 ConnectFrequencyMapDated connect_count_by_frequency_dated_;
Wade Guthrie60a37062013-04-02 11:39:09 -0700216
217 // Count of successful wifi connections we've made.
218 int64_t total_frequency_connections_;
219
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700220 Time *time_;
221
Paul Stewart21f2aae2013-01-17 17:10:08 -0800222 DISALLOW_COPY_AND_ASSIGN(WiFiProvider);
223};
224
225} // namespace shill
226
Wade Guthrie60a37062013-04-02 11:39:09 -0700227#endif // SHILL_WIFI_PROVIDER_H_