Home | History | Annotate | Download | only in wifi
      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 {
     59     FrequencyCount() : frequency(0), connection_count(0) {}
     60     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 
    142   bool disable_vht() { return 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