1 /* 2 * Copyright (C) 2017 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 package com.android.server.wifi; 17 18 import android.net.wifi.ScanResult; 19 import android.net.wifi.WifiConfiguration; 20 21 import com.android.server.wifi.util.ScanResultUtil; 22 23 import java.util.Objects; 24 25 /** 26 * Class to store the info needed to match a scan result to the provided network configuration. 27 */ 28 public class ScanResultMatchInfo { 29 /** 30 * SSID of the network. 31 */ 32 public String networkSsid; 33 /** 34 * Security Type of the network. 35 */ 36 public @WifiConfiguration.SecurityType int networkType; 37 /** 38 * Special flag for PSK-SAE in transition mode 39 */ 40 public boolean pskSaeInTransitionMode; 41 /** 42 * Special flag for OWE in transition mode 43 */ 44 public boolean oweInTransitionMode; 45 46 /** 47 * Fetch network type from network configuration. 48 */ getNetworkType(WifiConfiguration config)49 public static @WifiConfiguration.SecurityType int getNetworkType(WifiConfiguration config) { 50 if (WifiConfigurationUtil.isConfigForSaeNetwork(config)) { 51 return WifiConfiguration.SECURITY_TYPE_SAE; 52 } else if (WifiConfigurationUtil.isConfigForPskNetwork(config)) { 53 return WifiConfiguration.SECURITY_TYPE_PSK; 54 } else if (WifiConfigurationUtil.isConfigForEapNetwork(config)) { 55 return WifiConfiguration.SECURITY_TYPE_EAP; 56 } else if (WifiConfigurationUtil.isConfigForEapSuiteBNetwork(config)) { 57 return WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B; 58 } else if (WifiConfigurationUtil.isConfigForWepNetwork(config)) { 59 return WifiConfiguration.SECURITY_TYPE_WEP; 60 } else if (WifiConfigurationUtil.isConfigForOweNetwork(config)) { 61 return WifiConfiguration.SECURITY_TYPE_OWE; 62 } else if (WifiConfigurationUtil.isConfigForOpenNetwork(config)) { 63 return WifiConfiguration.SECURITY_TYPE_OPEN; 64 } 65 throw new IllegalArgumentException("Invalid WifiConfiguration: " + config); 66 } 67 68 /** 69 * Get the ScanResultMatchInfo for the given WifiConfiguration 70 */ fromWifiConfiguration(WifiConfiguration config)71 public static ScanResultMatchInfo fromWifiConfiguration(WifiConfiguration config) { 72 ScanResultMatchInfo info = new ScanResultMatchInfo(); 73 info.networkSsid = config.SSID; 74 info.networkType = getNetworkType(config); 75 return info; 76 } 77 78 /** 79 * Fetch network type from scan result. 80 */ getNetworkType(ScanResult scanResult)81 public static @WifiConfiguration.SecurityType int getNetworkType(ScanResult scanResult) { 82 if (ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { 83 return WifiConfiguration.SECURITY_TYPE_SAE; 84 } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) { 85 return WifiConfiguration.SECURITY_TYPE_PSK; 86 } else if (ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { 87 return WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B; 88 } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) { 89 return WifiConfiguration.SECURITY_TYPE_EAP; 90 } else if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) { 91 return WifiConfiguration.SECURITY_TYPE_WEP; 92 } else if (ScanResultUtil.isScanResultForOweNetwork(scanResult)) { 93 return WifiConfiguration.SECURITY_TYPE_OWE; 94 } else if (ScanResultUtil.isScanResultForOpenNetwork(scanResult)) { 95 return WifiConfiguration.SECURITY_TYPE_OPEN; 96 } else { 97 throw new IllegalArgumentException("Invalid ScanResult: " + scanResult); 98 } 99 } 100 101 /** 102 * Get the ScanResultMatchInfo for the given ScanResult 103 */ fromScanResult(ScanResult scanResult)104 public static ScanResultMatchInfo fromScanResult(ScanResult scanResult) { 105 ScanResultMatchInfo info = new ScanResultMatchInfo(); 106 // Scan result ssid's are not quoted, hence add quotes. 107 // TODO: This matching algo works only if the scan result contains a string SSID. 108 // However, according to our public documentation ths {@link WifiConfiguration#SSID} can 109 // either have a hex string or quoted ASCII string SSID. 110 info.networkSsid = ScanResultUtil.createQuotedSSID(scanResult.SSID); 111 info.networkType = getNetworkType(scanResult); 112 info.oweInTransitionMode = false; 113 info.pskSaeInTransitionMode = false; 114 if (info.networkType == WifiConfiguration.SECURITY_TYPE_SAE) { 115 // Note that scan result util will always choose the highest security protocol. 116 info.pskSaeInTransitionMode = 117 ScanResultUtil.isScanResultForPskSaeTransitionNetwork(scanResult); 118 } else if (info.networkType == WifiConfiguration.SECURITY_TYPE_OWE) { 119 // Note that scan result util will always choose OWE. 120 info.oweInTransitionMode = 121 ScanResultUtil.isScanResultForOweTransitionNetwork(scanResult); 122 } 123 return info; 124 } 125 126 @Override equals(Object otherObj)127 public boolean equals(Object otherObj) { 128 if (this == otherObj) { 129 return true; 130 } else if (!(otherObj instanceof ScanResultMatchInfo)) { 131 return false; 132 } 133 ScanResultMatchInfo other = (ScanResultMatchInfo) otherObj; 134 if (!Objects.equals(networkSsid, other.networkSsid)) { 135 return false; 136 } 137 boolean networkTypeEquals; 138 139 // Detect <SSID, PSK+SAE> scan result and say it is equal to <SSID, PSK> configuration 140 if (other.pskSaeInTransitionMode && networkType == WifiConfiguration.SECURITY_TYPE_PSK 141 || (pskSaeInTransitionMode 142 && other.networkType == WifiConfiguration.SECURITY_TYPE_PSK)) { 143 networkTypeEquals = true; 144 } else if ((networkType == WifiConfiguration.SECURITY_TYPE_OPEN 145 && other.oweInTransitionMode) || (oweInTransitionMode 146 && other.networkType == WifiConfiguration.SECURITY_TYPE_OPEN)) { 147 // Special case we treat Enhanced Open and Open as equals. This is done to support the 148 // case where a saved network is Open but we found an OWE in transition network. 149 networkTypeEquals = true; 150 } else { 151 networkTypeEquals = networkType == other.networkType; 152 } 153 return networkTypeEquals; 154 } 155 156 @Override hashCode()157 public int hashCode() { 158 return Objects.hash(networkSsid); 159 } 160 161 @Override toString()162 public String toString() { 163 return "ScanResultMatchInfo: ssid: " + networkSsid + ", type: " + networkType; 164 } 165 } 166