1 // 2 // Copyright (C) 2013 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef SHILL_WIFI_WIFI_PROVIDER_H_ 18 #define SHILL_WIFI_WIFI_PROVIDER_H_ 19 20 #include <time.h> 21 22 #include <deque> 23 #include <map> 24 #include <string> 25 #include <vector> 26 27 #include <gtest/gtest_prod.h> // for FRIEND_TEST 28 29 #include "shill/accessor_interface.h" // for ByteArrays 30 #include "shill/provider_interface.h" 31 #include "shill/refptr_types.h" 32 33 namespace shill { 34 35 class ByteString; 36 class ControlInterface; 37 class Error; 38 class EventDispatcher; 39 class KeyValueStore; 40 class Manager; 41 class Metrics; 42 class StoreInterface; 43 class Time; 44 class WiFiEndpoint; 45 class WiFiService; 46 47 // The WiFi Provider is the holder of all WiFi Services. It holds both 48 // visible (created due to an Endpoint becoming visible) and invisible 49 // (created due to user or storage configuration) Services. 50 class WiFiProvider : public ProviderInterface { 51 public: 52 static const char kStorageFrequencies[]; 53 static const int kMaxStorageFrequencies; 54 typedef std::map<uint16_t, int64_t> ConnectFrequencyMap; 55 // The key to |ConnectFrequencyMapDated| is the number of days since the 56 // Epoch. 57 typedef std::map<time_t, ConnectFrequencyMap> ConnectFrequencyMapDated; 58 struct FrequencyCount { FrequencyCountFrequencyCount59 FrequencyCount() : frequency(0), connection_count(0) {} FrequencyCountFrequencyCount60 FrequencyCount(uint16_t freq, size_t conn) 61 : frequency(freq), connection_count(conn) {} 62 uint16_t frequency; 63 size_t connection_count; // Number of successful connections at this 64 // frequency. 65 }; 66 typedef std::deque<FrequencyCount> FrequencyCountList; 67 68 WiFiProvider(ControlInterface* control_interface, 69 EventDispatcher* dispatcher, 70 Metrics* metrics, 71 Manager* manager); 72 ~WiFiProvider() override; 73 74 // Called by Manager as a part of the Provider interface. The attributes 75 // used for matching services for the WiFi provider are the SSID, mode and 76 // security parameters. 77 void CreateServicesFromProfile(const ProfileRefPtr& profile) override; 78 ServiceRefPtr FindSimilarService( 79 const KeyValueStore& args, Error* error) const override; 80 ServiceRefPtr GetService(const KeyValueStore& args, Error* error) override; 81 ServiceRefPtr CreateTemporaryService( 82 const KeyValueStore& args, Error* error) override; 83 ServiceRefPtr CreateTemporaryServiceFromProfile( 84 const ProfileRefPtr& profile, 85 const std::string& entry_name, 86 Error* error) override; 87 void Start() override; 88 void Stop() override; 89 90 // Find a Service this Endpoint should be associated with. 91 virtual WiFiServiceRefPtr FindServiceForEndpoint( 92 const WiFiEndpointConstRefPtr& endpoint); 93 94 // Find or create a Service for |endpoint| to be associated with. This 95 // method first calls FindServiceForEndpoint, and failing this, creates 96 // a new Service. It then associates |endpoint| with this service. 97 virtual void OnEndpointAdded(const WiFiEndpointConstRefPtr& endpoint); 98 99 // Called by a Device when it removes an Endpoint. If the Provider 100 // forgets a service as a result, it returns a reference to the 101 // forgotten service, otherwise it returns a null reference. 102 virtual WiFiServiceRefPtr OnEndpointRemoved( 103 const WiFiEndpointConstRefPtr& endpoint); 104 105 // Called by a Device when it receives notification that an Endpoint 106 // has changed. Ensure the updated endpoint still matches its 107 // associated service. If necessary re-assign the endpoint to a new 108 // service, otherwise notify the associated service of the update to 109 // the endpoint. 110 virtual void OnEndpointUpdated(const WiFiEndpointConstRefPtr& endpoint); 111 112 // Called by a WiFiService when it is unloaded and no longer visible. 113 virtual bool OnServiceUnloaded(const WiFiServiceRefPtr& service); 114 115 // Get the list of SSIDs for hidden WiFi services we are aware of. 116 virtual ByteArrays GetHiddenSSIDList(); 117 118 // Calls WiFiService::FixupServiceEntries() and adds a UMA metric if 119 // this causes entries to be updated. 120 virtual void LoadAndFixupServiceEntries(Profile* profile); 121 122 // Save configuration for wifi_provider to |storage|. 123 virtual bool Save(StoreInterface* storage) const; 124 125 virtual void IncrementConnectCount(uint16_t frequency_mhz); 126 127 // Returns a list of all of the frequencies on which this device has 128 // connected. This data is accumulated across multiple shill runs. 129 virtual FrequencyCountList GetScanFrequencies() const; 130 131 // Report the number of auto connectable services available to uma 132 // metrics. 133 void ReportAutoConnectableServices(); 134 135 // Returns number of services available for auto-connect. 136 virtual int NumAutoConnectableServices(); 137 138 // Returns a list of ByteStrings representing the SSIDs of WiFi services 139 // configured for auto-connect. 140 std::vector<ByteString> GetSsidsConfiguredForAutoConnect(); 141 disable_vht()142 bool disable_vht() { return disable_vht_; } set_disable_vht(bool disable_vht)143 void set_disable_vht(bool disable_vht) { disable_vht_ = disable_vht; } 144 145 private: 146 friend class WiFiProviderTest; 147 FRIEND_TEST(WiFiProviderTest, FrequencyMapAgingIllegalDay); 148 FRIEND_TEST(WiFiProviderTest, FrequencyMapBasicAging); 149 FRIEND_TEST(WiFiProviderTest, FrequencyMapToStringList); 150 FRIEND_TEST(WiFiProviderTest, FrequencyMapToStringListEmpty); 151 FRIEND_TEST(WiFiProviderTest, IncrementConnectCount); 152 FRIEND_TEST(WiFiProviderTest, IncrementConnectCountCreateNew); 153 FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntriesDefaultProfile); 154 FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntriesUserProfile); 155 FRIEND_TEST(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo); 156 FRIEND_TEST(WiFiProviderTest, StringListToFrequencyMap); 157 FRIEND_TEST(WiFiProviderTest, StringListToFrequencyMapEmpty); 158 159 typedef std::map<const WiFiEndpoint*, WiFiServiceRefPtr> EndpointServiceMap; 160 161 static const char kManagerErrorSSIDTooLong[]; 162 static const char kManagerErrorSSIDTooShort[]; 163 static const char kManagerErrorSSIDRequired[]; 164 static const char kManagerErrorUnsupportedSecurityClass[]; 165 static const char kManagerErrorUnsupportedSecurityMode[]; 166 static const char kManagerErrorUnsupportedServiceMode[]; 167 static const char kManagerErrorArgumentConflict[]; 168 static const char kFrequencyDelimiter; 169 static const char kStartWeekHeader[]; 170 static const time_t kIllegalStartWeek; 171 static const char kStorageId[]; 172 static const time_t kWeeksToKeepFrequencyCounts; 173 static const time_t kSecondsPerWeek; 174 175 // Add a service to the service_ vector and register it with the Manager. 176 WiFiServiceRefPtr AddService(const std::vector<uint8_t>& ssid, 177 const std::string& mode, 178 const std::string& security, 179 bool is_hidden); 180 181 // Find a service given its properties. 182 WiFiServiceRefPtr FindService(const std::vector<uint8_t>& ssid, 183 const std::string& mode, 184 const std::string& security) const; 185 186 // Returns a WiFiServiceRefPtr for unit tests and for down-casting to a 187 // ServiceRefPtr in GetService(). 188 WiFiServiceRefPtr GetWiFiService(const KeyValueStore& args, Error* error); 189 190 // Disassociate the service from its WiFi device and remove it from the 191 // services_ vector. 192 void ForgetService(const WiFiServiceRefPtr& service); 193 194 void ReportRememberedNetworkCount(); 195 void ReportServiceSourceMetrics(); 196 197 // Retrieve a WiFi service's identifying properties from passed-in |args|. 198 // Returns true if |args| are valid and populates |ssid|, |mode|, 199 // |security| and |hidden_ssid|, if successful. Otherwise, this function 200 // returns false and populates |error| with the reason for failure. It 201 // is a fatal error if the "Type" parameter passed in |args| is not kWiFi. 202 static bool GetServiceParametersFromArgs(const KeyValueStore& args, 203 std::vector<uint8_t>* ssid_bytes, 204 std::string* mode, 205 std::string* security_method, 206 bool* hidden_ssid, 207 Error* error); 208 // Retrieve a WiFi service's identifying properties from passed-in |storage|. 209 // Return true if storage contain valid parameter values and populates |ssid|, 210 // |mode|, |security| and |hidden_ssid|. Otherwise, this function returns 211 // false and populates |error| with the reason for failure. 212 static bool GetServiceParametersFromStorage(const StoreInterface* storage, 213 const std::string& entry_name, 214 std::vector<uint8_t>* ssid_bytes, 215 std::string* mode, 216 std::string* security_method, 217 bool* hidden_ssid, 218 Error* error); 219 220 // Converts frequency profile information from a list of strings of the form 221 // "frequency:connection_count" to a form consistent with 222 // |connect_count_by_frequency_|. The first string must be of the form 223 // [nnn] where |nnn| is a positive integer that represents the creation time 224 // (number of days since the Epoch) of the data. 225 static time_t StringListToFrequencyMap( 226 const std::vector<std::string>& strings, 227 ConnectFrequencyMap* numbers); 228 229 // Extracts the start week from the first string in the StringList for 230 // |StringListToFrequencyMap|. 231 static time_t GetStringListStartWeek(const std::string& week_string); 232 233 // Extracts frequency and connection count from a string from the StringList 234 // for |StringListToFrequencyMap|. Places those values in |numbers|. 235 static void ParseStringListFreqCount(const std::string& freq_count_string, 236 ConnectFrequencyMap* numbers); 237 238 // Converts frequency profile information from a form consistent with 239 // |connect_count_by_frequency_| to a list of strings of the form 240 // "frequency:connection_count". The |creation_day| is the day that the 241 // data was first createed (represented as the number of days since the 242 // Epoch). 243 static void FrequencyMapToStringList(time_t creation_day, 244 const ConnectFrequencyMap& numbers, 245 std::vector<std::string>* strings); 246 247 ControlInterface* control_interface_; 248 EventDispatcher* dispatcher_; 249 Metrics* metrics_; 250 Manager* manager_; 251 252 std::vector<WiFiServiceRefPtr> services_; 253 EndpointServiceMap service_by_endpoint_; 254 255 bool running_; 256 257 // Map of frequencies at which we've connected and the number of times a 258 // successful connection has been made at that frequency. Absent frequencies 259 // have not had a successful connection. 260 ConnectFrequencyMap connect_count_by_frequency_; 261 // A number of entries of |ConnectFrequencyMap| stored by date of creation. 262 ConnectFrequencyMapDated connect_count_by_frequency_dated_; 263 264 // Count of successful wifi connections we've made. 265 int64_t total_frequency_connections_; 266 267 Time* time_; 268 269 // Disable 802.11ac Very High Throughput (VHT) connections. 270 bool disable_vht_; 271 272 DISALLOW_COPY_AND_ASSIGN(WiFiProvider); 273 }; 274 275 } // namespace shill 276 277 #endif // SHILL_WIFI_WIFI_PROVIDER_H_ 278