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