Home | History | Annotate | Download | only in wifi
      1 //
      2 // Copyright (C) 2012 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_ENDPOINT_H_
     18 #define SHILL_WIFI_WIFI_ENDPOINT_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 #include <set>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include <base/memory/ref_counted.h>
     27 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     28 
     29 #include "shill/event_dispatcher.h"
     30 #include "shill/key_value_store.h"
     31 #include "shill/metrics.h"
     32 #include "shill/refptr_types.h"
     33 
     34 namespace shill {
     35 
     36 class ControlInterface;
     37 class SupplicantBSSProxyInterface;
     38 
     39 class WiFiEndpoint : public base::RefCounted<WiFiEndpoint> {
     40  public:
     41   struct SecurityFlags {
     42     SecurityFlags()
     43         : rsn_8021x(false),
     44           rsn_psk(false),
     45           wpa_8021x(false),
     46           wpa_psk(false),
     47           privacy(false) {}
     48     bool rsn_8021x;
     49     bool rsn_psk;
     50     bool wpa_8021x;
     51     bool wpa_psk;
     52     bool privacy;
     53   };
     54   struct VendorInformation {
     55     std::string wps_manufacturer;
     56     std::string wps_model_name;
     57     std::string wps_model_number;
     58     std::string wps_device_name;
     59     std::set<uint32_t> oui_set;
     60   };
     61   WiFiEndpoint(ControlInterface* control_interface,
     62                const WiFiRefPtr& device,
     63                const std::string& rpc_id,
     64                const KeyValueStore& properties);
     65   virtual ~WiFiEndpoint();
     66 
     67   // Set up RPC channel. Broken out from the ctor, so that WiFi can
     68   // look over the Endpoint details before commiting to setting up
     69   // RPC.
     70   virtual void Start();
     71 
     72   // Called by SupplicantBSSProxy, in response to events from
     73   // wpa_supplicant.
     74   void PropertiesChanged(const KeyValueStore& properties);
     75 
     76   // Called by WiFi when it polls for signal strength from the kernel.
     77   void UpdateSignalStrength(int16_t strength);
     78 
     79   // Maps mode strings from flimflam's nomenclature, as defined
     80   // in chromeos/dbus/service_constants.h, to uints used by supplicant
     81   static uint32_t ModeStringToUint(const std::string& mode_string);
     82 
     83   // Returns a stringmap containing information gleaned about the
     84   // vendor of this AP.
     85   std::map<std::string, std::string> GetVendorInformation() const;
     86 
     87   const std::vector<uint8_t>& ssid() const;
     88   const std::string& ssid_string() const;
     89   const std::string& ssid_hex() const;
     90   const std::string& bssid_string() const;
     91   const std::string& bssid_hex() const;
     92   const std::string& country_code() const;
     93   const WiFiRefPtr& device() const;
     94   int16_t signal_strength() const;
     95   uint16_t frequency() const;
     96   uint16_t physical_mode() const;
     97   const std::string& network_mode() const;
     98   const std::string& security_mode() const;
     99   bool ieee80211w_required() const;
    100   bool has_rsn_property() const;
    101   bool has_wpa_property() const;
    102   bool has_tethering_signature() const;
    103 
    104  private:
    105   friend class WiFiEndpointTest;
    106   friend class WiFiObjectTest;  // for MakeOpenEndpoint
    107   friend class WiFiProviderTest;  // for MakeOpenEndpoint
    108   friend class WiFiServiceTest;  // for MakeOpenEndpoint
    109   // these test cases need access to the KeyManagement enum
    110   FRIEND_TEST(WiFiEndpointTest, DeterminePhyModeFromFrequency);
    111   FRIEND_TEST(WiFiEndpointTest, ParseKeyManagementMethodsEAP);
    112   FRIEND_TEST(WiFiEndpointTest, ParseKeyManagementMethodsPSK);
    113   FRIEND_TEST(WiFiEndpointTest, ParseKeyManagementMethodsEAPAndPSK);
    114   FRIEND_TEST(WiFiEndpointTest, HasTetheringSignature);
    115   FRIEND_TEST(WiFiProviderTest, OnEndpointAddedWithSecurity);
    116   FRIEND_TEST(WiFiProviderTest, OnEndpointUpdated);
    117   FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA80211w);
    118   FRIEND_TEST(WiFiServiceTest, GetTethering);
    119   FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest, EndpointModified);
    120   FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest, Ieee80211w);
    121   // for physical_mode_
    122   FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest, PhysicalMode);
    123 
    124   enum KeyManagement {
    125     kKeyManagement802_1x,
    126     kKeyManagementPSK
    127   };
    128 
    129   // Build a simple WiFiEndpoint, for testing purposes.
    130   static WiFiEndpoint* MakeEndpoint(ControlInterface* control_interface,
    131                                     const WiFiRefPtr& wifi,
    132                                     const std::string& ssid,
    133                                     const std::string& bssid,
    134                                     const std::string& network_mode,
    135                                     uint16_t frequency,
    136                                     int16_t signal_dbm,
    137                                     bool has_wpa_property,
    138                                     bool has_rsn_property);
    139   // As above, but with the last two parameters false.
    140   static WiFiEndpoint* MakeOpenEndpoint(ControlInterface* control_interface,
    141                                         const WiFiRefPtr& wifi,
    142                                         const std::string& ssid,
    143                                         const std::string& bssid,
    144                                         const std::string& network_mode,
    145                                         uint16_t frequency,
    146                                         int16_t signal_dbm);
    147   // Maps mode strings from supplicant into flimflam's nomenclature, as defined
    148   // in chromeos/dbus/service_constants.h.
    149   static const char* ParseMode(const std::string& mode_string);
    150   // Parses an Endpoint's properties to identify an approprirate flimflam
    151   // security property value, as defined in chromeos/dbus/service_constants.h.
    152   // The stored data in the |flags| parameter is merged with the provided
    153   // properties, and the security value returned is the result of the
    154   // merger.
    155   static const char* ParseSecurity(const KeyValueStore& properties,
    156                                    SecurityFlags* flags);
    157   // Parses an Endpoint's properties' "RSN" or "WPA" sub-dictionary, to
    158   // identify supported key management methods (802.1x or PSK).
    159   static void ParseKeyManagementMethods(
    160       const KeyValueStore& security_method_properties,
    161       std::set<KeyManagement>* key_management_methods);
    162   // Determine the negotiated operating mode for the channel by looking at
    163   // the information elements, frequency and data rates.  The information
    164   // elements and data rates live in |properties|.
    165   static Metrics::WiFiNetworkPhyMode DeterminePhyModeFromFrequency(
    166       const KeyValueStore& properties,
    167       uint16_t frequency);
    168   // Parse information elements to determine the physical mode, vendor
    169   // information and IEEE 802.11w requirement information associated
    170   // with the AP.  Returns true if a physical mode was determined from
    171   // the IE elements, false otherwise.
    172   static bool ParseIEs(const KeyValueStore& properties,
    173                        Metrics::WiFiNetworkPhyMode* phy_mode,
    174                        VendorInformation* vendor_information,
    175                        bool* ieee80211w_required, std::string* country_code);
    176   // Parse a WPA information element and set *|ieee80211w_required| to true
    177   // if IEEE 802.11w is required by this AP.
    178   static void ParseWPACapabilities(std::vector<uint8_t>::const_iterator ie,
    179                                    std::vector<uint8_t>::const_iterator end,
    180                                    bool* ieee80211w_required);
    181   // Parse a single vendor information element.  If this is a WPA vendor
    182   // element, call ParseWPACapabilites with |ieee80211w_required|.
    183   static void ParseVendorIE(std::vector<uint8_t>::const_iterator ie,
    184                             std::vector<uint8_t>::const_iterator end,
    185                             VendorInformation* vendor_information,
    186                             bool* ieee80211w_required);
    187 
    188   // Assigns a value to |has_tethering_signature_|.
    189   void CheckForTetheringSignature();
    190 
    191   // Private setter used in unit tests.
    192   void set_security_mode(const std::string& mode) { security_mode_ = mode; }
    193 
    194   // TODO(quiche): make const?
    195   std::vector<uint8_t> ssid_;
    196   std::vector<uint8_t> bssid_;
    197   std::string ssid_string_;
    198   std::string ssid_hex_;
    199   std::string bssid_string_;
    200   std::string bssid_hex_;
    201   std::string country_code_;
    202   int16_t signal_strength_;
    203   uint16_t frequency_;
    204   uint16_t physical_mode_;
    205   // network_mode_ and security_mode_ are represented as flimflam names
    206   // (not necessarily the same as wpa_supplicant names)
    207   std::string network_mode_;
    208   std::string security_mode_;
    209   VendorInformation vendor_information_;
    210   bool ieee80211w_required_;
    211   bool has_rsn_property_;
    212   bool has_wpa_property_;
    213   bool has_tethering_signature_;
    214   SecurityFlags security_flags_;
    215 
    216   ControlInterface* control_interface_;
    217   WiFiRefPtr device_;
    218   std::string rpc_id_;
    219   std::unique_ptr<SupplicantBSSProxyInterface> supplicant_bss_proxy_;
    220 
    221   DISALLOW_COPY_AND_ASSIGN(WiFiEndpoint);
    222 };
    223 
    224 }  // namespace shill
    225 
    226 #endif  // SHILL_WIFI_WIFI_ENDPOINT_H_
    227