Home | History | Annotate | Download | only in net
      1 // Copyright 2014 The Chromium 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 #include "components/metrics/net/wifi_access_point_info_provider_chromeos.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/location.h"
      9 #include "base/strings/string_number_conversions.h"
     10 #include "chromeos/network/network_configuration_handler.h"
     11 #include "chromeos/network/network_handler.h"
     12 #include "chromeos/network/network_state.h"
     13 #include "chromeos/network/network_state_handler.h"
     14 #include "chromeos/network/shill_property_util.h"
     15 #include "third_party/cros_system_api/dbus/service_constants.h"
     16 
     17 using chromeos::NetworkHandler;
     18 
     19 WifiAccessPointInfoProviderChromeos::WifiAccessPointInfoProviderChromeos() {
     20   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
     21 
     22   // Update initial connection state.
     23   DefaultNetworkChanged(
     24       NetworkHandler::Get()->network_state_handler()->DefaultNetwork());
     25 }
     26 
     27 WifiAccessPointInfoProviderChromeos::~WifiAccessPointInfoProviderChromeos() {
     28   NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
     29                                                                  FROM_HERE);
     30 }
     31 
     32 bool WifiAccessPointInfoProviderChromeos::GetInfo(WifiAccessPointInfo* info) {
     33   // Wifi access point information is not provided if the BSSID is empty.
     34   // This assumes the BSSID is never empty when access point information exists.
     35   if (wifi_access_point_info_.bssid.empty())
     36     return false;
     37 
     38   *info = wifi_access_point_info_;
     39   return true;
     40 }
     41 
     42 void WifiAccessPointInfoProviderChromeos::DefaultNetworkChanged(
     43     const chromeos::NetworkState* default_network) {
     44   // Reset access point info to prevent reporting of out-dated data.
     45   wifi_access_point_info_ = WifiAccessPointInfo();
     46 
     47   // Skip non-wifi connections
     48   if (!default_network || default_network->type() != shill::kTypeWifi)
     49     return;
     50 
     51   // Retrieve access point info for wifi connection.
     52   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
     53       default_network->path(),
     54       base::Bind(&WifiAccessPointInfoProviderChromeos::ParseInfo,
     55                  AsWeakPtr()),
     56       chromeos::network_handler::ErrorCallback());
     57 }
     58 
     59 void WifiAccessPointInfoProviderChromeos::ParseInfo(
     60     const std::string &service_path,
     61     const base::DictionaryValue& properties) {
     62   // Skip services that contain "_nomap" in the SSID.
     63   std::string ssid =
     64       chromeos::shill_property_util::GetSSIDFromProperties(properties, NULL);
     65   if (ssid.find("_nomap", 0) != std::string::npos)
     66     return;
     67 
     68   std::string bssid;
     69   if (!properties.GetStringWithoutPathExpansion(shill::kWifiBSsid, &bssid) ||
     70       bssid.empty())
     71     return;
     72 
     73   // Filter out BSSID with local bit set in the first byte.
     74   uint32 first_octet;
     75   if (!base::HexStringToUInt(bssid.substr(0, 2), &first_octet))
     76     NOTREACHED();
     77   if (first_octet & 0x2)
     78     return;
     79   wifi_access_point_info_.bssid = bssid;
     80 
     81   // Parse security info.
     82   std::string security;
     83   properties.GetStringWithoutPathExpansion(
     84       shill::kSecurityProperty, &security);
     85   wifi_access_point_info_.security = WIFI_SECURITY_UNKNOWN;
     86   if (security == shill::kSecurityWpa)
     87     wifi_access_point_info_.security = WIFI_SECURITY_WPA;
     88   else if (security == shill::kSecurityWep)
     89     wifi_access_point_info_.security = WIFI_SECURITY_WEP;
     90   else if (security == shill::kSecurityRsn)
     91     wifi_access_point_info_.security = WIFI_SECURITY_RSN;
     92   else if (security == shill::kSecurity8021x)
     93     wifi_access_point_info_.security = WIFI_SECURITY_802_1X;
     94   else if (security == shill::kSecurityPsk)
     95     wifi_access_point_info_.security = WIFI_SECURITY_PSK;
     96   else if (security == shill::kSecurityNone)
     97     wifi_access_point_info_.security = WIFI_SECURITY_NONE;
     98 
     99   properties.GetStringWithoutPathExpansion(
    100       shill::kWifiBSsid, &wifi_access_point_info_.bssid);
    101   const base::DictionaryValue* vendor_dict = NULL;
    102   if (!properties.GetDictionaryWithoutPathExpansion(
    103           shill::kWifiVendorInformationProperty,
    104           &vendor_dict))
    105     return;
    106 
    107   vendor_dict->GetStringWithoutPathExpansion(
    108       shill::kVendorWPSModelNumberProperty,
    109       &wifi_access_point_info_.model_number);
    110   vendor_dict->GetStringWithoutPathExpansion(
    111       shill::kVendorWPSModelNameProperty,
    112       &wifi_access_point_info_.model_name);
    113   vendor_dict->GetStringWithoutPathExpansion(
    114       shill::kVendorWPSDeviceNameProperty,
    115       &wifi_access_point_info_.device_name);
    116   vendor_dict->GetStringWithoutPathExpansion(shill::kVendorOUIListProperty,
    117                                              &wifi_access_point_info_.oui_list);
    118 }
    119