// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/metrics/net/wifi_access_point_info_provider_chromeos.h" #include "base/bind.h" #include "base/location.h" #include "base/strings/string_number_conversions.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/shill_property_util.h" #include "third_party/cros_system_api/dbus/service_constants.h" using chromeos::NetworkHandler; namespace metrics { WifiAccessPointInfoProviderChromeos::WifiAccessPointInfoProviderChromeos() { NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); // Update initial connection state. DefaultNetworkChanged( NetworkHandler::Get()->network_state_handler()->DefaultNetwork()); } WifiAccessPointInfoProviderChromeos::~WifiAccessPointInfoProviderChromeos() { NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, FROM_HERE); } bool WifiAccessPointInfoProviderChromeos::GetInfo(WifiAccessPointInfo* info) { // Wifi access point information is not provided if the BSSID is empty. // This assumes the BSSID is never empty when access point information exists. if (wifi_access_point_info_.bssid.empty()) return false; *info = wifi_access_point_info_; return true; } void WifiAccessPointInfoProviderChromeos::DefaultNetworkChanged( const chromeos::NetworkState* default_network) { // Reset access point info to prevent reporting of out-dated data. wifi_access_point_info_ = WifiAccessPointInfo(); // Skip non-wifi connections if (!default_network || default_network->type() != shill::kTypeWifi) return; // Retrieve access point info for wifi connection. NetworkHandler::Get()->network_configuration_handler()->GetShillProperties( default_network->path(), base::Bind(&WifiAccessPointInfoProviderChromeos::ParseInfo, AsWeakPtr()), chromeos::network_handler::ErrorCallback()); } void WifiAccessPointInfoProviderChromeos::ParseInfo( const std::string &service_path, const base::DictionaryValue& properties) { // Skip services that contain "_nomap" in the SSID. std::string ssid = chromeos::shill_property_util::GetSSIDFromProperties( properties, false /* verbose_logging */, nullptr); if (ssid.find("_nomap", 0) != std::string::npos) return; std::string bssid; if (!properties.GetStringWithoutPathExpansion(shill::kWifiBSsid, &bssid) || bssid.empty()) return; // Filter out BSSID with local bit set in the first byte. uint32 first_octet; if (!base::HexStringToUInt(bssid.substr(0, 2), &first_octet)) NOTREACHED(); if (first_octet & 0x2) return; wifi_access_point_info_.bssid = bssid; // Parse security info. std::string security; properties.GetStringWithoutPathExpansion( shill::kSecurityProperty, &security); wifi_access_point_info_.security = WIFI_SECURITY_UNKNOWN; if (security == shill::kSecurityWpa) wifi_access_point_info_.security = WIFI_SECURITY_WPA; else if (security == shill::kSecurityWep) wifi_access_point_info_.security = WIFI_SECURITY_WEP; else if (security == shill::kSecurityRsn) wifi_access_point_info_.security = WIFI_SECURITY_RSN; else if (security == shill::kSecurity8021x) wifi_access_point_info_.security = WIFI_SECURITY_802_1X; else if (security == shill::kSecurityPsk) wifi_access_point_info_.security = WIFI_SECURITY_PSK; else if (security == shill::kSecurityNone) wifi_access_point_info_.security = WIFI_SECURITY_NONE; properties.GetStringWithoutPathExpansion( shill::kWifiBSsid, &wifi_access_point_info_.bssid); const base::DictionaryValue* vendor_dict = NULL; if (!properties.GetDictionaryWithoutPathExpansion( shill::kWifiVendorInformationProperty, &vendor_dict)) return; vendor_dict->GetStringWithoutPathExpansion( shill::kVendorWPSModelNumberProperty, &wifi_access_point_info_.model_number); vendor_dict->GetStringWithoutPathExpansion( shill::kVendorWPSModelNameProperty, &wifi_access_point_info_.model_name); vendor_dict->GetStringWithoutPathExpansion( shill::kVendorWPSDeviceNameProperty, &wifi_access_point_info_.device_name); vendor_dict->GetStringWithoutPathExpansion(shill::kVendorOUIListProperty, &wifi_access_point_info_.oui_list); } } // namespace metrics