// // Copyright (C) 2012 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef SHILL_WIFI_WIFI_ENDPOINT_H_ #define SHILL_WIFI_WIFI_ENDPOINT_H_ #include <map> #include <memory> #include <set> #include <string> #include <vector> #include <base/memory/ref_counted.h> #include <gtest/gtest_prod.h> // for FRIEND_TEST #include "shill/event_dispatcher.h" #include "shill/key_value_store.h" #include "shill/metrics.h" #include "shill/refptr_types.h" namespace shill { class ControlInterface; class SupplicantBSSProxyInterface; class WiFiEndpoint : public base::RefCounted<WiFiEndpoint> { public: struct SecurityFlags { SecurityFlags() : rsn_8021x(false), rsn_psk(false), wpa_8021x(false), wpa_psk(false), privacy(false) {} bool rsn_8021x; bool rsn_psk; bool wpa_8021x; bool wpa_psk; bool privacy; }; struct VendorInformation { std::string wps_manufacturer; std::string wps_model_name; std::string wps_model_number; std::string wps_device_name; std::set<uint32_t> oui_set; }; WiFiEndpoint(ControlInterface* control_interface, const WiFiRefPtr& device, const std::string& rpc_id, const KeyValueStore& properties); virtual ~WiFiEndpoint(); // Set up RPC channel. Broken out from the ctor, so that WiFi can // look over the Endpoint details before commiting to setting up // RPC. virtual void Start(); // Called by SupplicantBSSProxy, in response to events from // wpa_supplicant. void PropertiesChanged(const KeyValueStore& properties); // Called by WiFi when it polls for signal strength from the kernel. void UpdateSignalStrength(int16_t strength); // Maps mode strings from flimflam's nomenclature, as defined // in chromeos/dbus/service_constants.h, to uints used by supplicant static uint32_t ModeStringToUint(const std::string& mode_string); // Returns a stringmap containing information gleaned about the // vendor of this AP. std::map<std::string, std::string> GetVendorInformation() const; const std::vector<uint8_t>& ssid() const; const std::string& ssid_string() const; const std::string& ssid_hex() const; const std::string& bssid_string() const; const std::string& bssid_hex() const; const std::string& country_code() const; const WiFiRefPtr& device() const; int16_t signal_strength() const; uint16_t frequency() const; uint16_t physical_mode() const; const std::string& network_mode() const; const std::string& security_mode() const; bool ieee80211w_required() const; bool has_rsn_property() const; bool has_wpa_property() const; bool has_tethering_signature() const; private: friend class WiFiEndpointTest; friend class WiFiObjectTest; // for MakeOpenEndpoint friend class WiFiProviderTest; // for MakeOpenEndpoint friend class WiFiServiceTest; // for MakeOpenEndpoint // these test cases need access to the KeyManagement enum FRIEND_TEST(WiFiEndpointTest, DeterminePhyModeFromFrequency); FRIEND_TEST(WiFiEndpointTest, ParseKeyManagementMethodsEAP); FRIEND_TEST(WiFiEndpointTest, ParseKeyManagementMethodsPSK); FRIEND_TEST(WiFiEndpointTest, ParseKeyManagementMethodsEAPAndPSK); FRIEND_TEST(WiFiEndpointTest, HasTetheringSignature); FRIEND_TEST(WiFiProviderTest, OnEndpointAddedWithSecurity); FRIEND_TEST(WiFiProviderTest, OnEndpointUpdated); FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA80211w); FRIEND_TEST(WiFiServiceTest, GetTethering); FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest, EndpointModified); FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest, Ieee80211w); // for physical_mode_ FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest, PhysicalMode); enum KeyManagement { kKeyManagement802_1x, kKeyManagementPSK }; // Build a simple WiFiEndpoint, for testing purposes. static WiFiEndpoint* MakeEndpoint(ControlInterface* control_interface, const WiFiRefPtr& wifi, const std::string& ssid, const std::string& bssid, const std::string& network_mode, uint16_t frequency, int16_t signal_dbm, bool has_wpa_property, bool has_rsn_property); // As above, but with the last two parameters false. static WiFiEndpoint* MakeOpenEndpoint(ControlInterface* control_interface, const WiFiRefPtr& wifi, const std::string& ssid, const std::string& bssid, const std::string& network_mode, uint16_t frequency, int16_t signal_dbm); // Maps mode strings from supplicant into flimflam's nomenclature, as defined // in chromeos/dbus/service_constants.h. static const char* ParseMode(const std::string& mode_string); // Parses an Endpoint's properties to identify an approprirate flimflam // security property value, as defined in chromeos/dbus/service_constants.h. // The stored data in the |flags| parameter is merged with the provided // properties, and the security value returned is the result of the // merger. static const char* ParseSecurity(const KeyValueStore& properties, SecurityFlags* flags); // Parses an Endpoint's properties' "RSN" or "WPA" sub-dictionary, to // identify supported key management methods (802.1x or PSK). static void ParseKeyManagementMethods( const KeyValueStore& security_method_properties, std::set<KeyManagement>* key_management_methods); // Determine the negotiated operating mode for the channel by looking at // the information elements, frequency and data rates. The information // elements and data rates live in |properties|. static Metrics::WiFiNetworkPhyMode DeterminePhyModeFromFrequency( const KeyValueStore& properties, uint16_t frequency); // Parse information elements to determine the physical mode, vendor // information and IEEE 802.11w requirement information associated // with the AP. Returns true if a physical mode was determined from // the IE elements, false otherwise. static bool ParseIEs(const KeyValueStore& properties, Metrics::WiFiNetworkPhyMode* phy_mode, VendorInformation* vendor_information, bool* ieee80211w_required, std::string* country_code); // Parse a WPA information element and set *|ieee80211w_required| to true // if IEEE 802.11w is required by this AP. static void ParseWPACapabilities(std::vector<uint8_t>::const_iterator ie, std::vector<uint8_t>::const_iterator end, bool* ieee80211w_required); // Parse a single vendor information element. If this is a WPA vendor // element, call ParseWPACapabilites with |ieee80211w_required|. static void ParseVendorIE(std::vector<uint8_t>::const_iterator ie, std::vector<uint8_t>::const_iterator end, VendorInformation* vendor_information, bool* ieee80211w_required); // Assigns a value to |has_tethering_signature_|. void CheckForTetheringSignature(); // Private setter used in unit tests. void set_security_mode(const std::string& mode) { security_mode_ = mode; } // TODO(quiche): make const? std::vector<uint8_t> ssid_; std::vector<uint8_t> bssid_; std::string ssid_string_; std::string ssid_hex_; std::string bssid_string_; std::string bssid_hex_; std::string country_code_; int16_t signal_strength_; uint16_t frequency_; uint16_t physical_mode_; // network_mode_ and security_mode_ are represented as flimflam names // (not necessarily the same as wpa_supplicant names) std::string network_mode_; std::string security_mode_; VendorInformation vendor_information_; bool ieee80211w_required_; bool has_rsn_property_; bool has_wpa_property_; bool has_tethering_signature_; SecurityFlags security_flags_; ControlInterface* control_interface_; WiFiRefPtr device_; std::string rpc_id_; std::unique_ptr<SupplicantBSSProxyInterface> supplicant_bss_proxy_; DISALLOW_COPY_AND_ASSIGN(WiFiEndpoint); }; } // namespace shill #endif // SHILL_WIFI_WIFI_ENDPOINT_H_