1 /* 2 * Copyright (C) 2016 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 package com.android.server.wifi.util; 18 19 import android.net.wifi.ScanResult; 20 import android.net.wifi.WifiConfiguration; 21 import android.text.TextUtils; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 import com.android.server.wifi.ScanDetail; 25 import com.android.server.wifi.WifiConfigurationUtil; 26 import com.android.server.wifi.hotspot2.NetworkDetail; 27 28 /** 29 * Scan result utility for any {@link ScanResult} related operations. 30 * Currently contains: 31 * > Helper method for converting a ScanResult to a ScanDetail. 32 * Only fields that are supported in ScanResult are copied. 33 * > Helper methods to identify the encryption of a ScanResult. 34 */ 35 public class ScanResultUtil { 36 private ScanResultUtil() { /* not constructable */ } 37 38 /** 39 * This method should only be used when the informationElements field in the provided scan 40 * result is filled in with the IEs from the beacon. 41 */ 42 public static ScanDetail toScanDetail(ScanResult scanResult) { 43 NetworkDetail networkDetail = new NetworkDetail(scanResult.BSSID, 44 scanResult.informationElements, scanResult.anqpLines, scanResult.frequency); 45 return new ScanDetail(scanResult, networkDetail); 46 } 47 48 /** 49 * Helper method to check if the provided |scanResult| corresponds to a PSK network or not. 50 * This checks if the provided capabilities string contains PSK encryption type or not. 51 */ 52 public static boolean isScanResultForPskNetwork(ScanResult scanResult) { 53 return scanResult.capabilities.contains("PSK"); 54 } 55 56 /** 57 * Helper method to check if the provided |scanResult| corresponds to a EAP network or not. 58 * This checks if the provided capabilities string contains EAP encryption type or not. 59 */ 60 public static boolean isScanResultForEapNetwork(ScanResult scanResult) { 61 return scanResult.capabilities.contains("EAP"); 62 } 63 64 /** 65 * Helper method to check if the provided |scanResult| corresponds to a WEP network or not. 66 * This checks if the provided capabilities string contains WEP encryption type or not. 67 */ 68 public static boolean isScanResultForWepNetwork(ScanResult scanResult) { 69 return scanResult.capabilities.contains("WEP"); 70 } 71 72 /** 73 * Helper method to check if the provided |scanResult| corresponds to an open network or not. 74 * This checks if the provided capabilities string does not contain either of WEP, PSK or EAP 75 * encryption types or not. 76 */ 77 public static boolean isScanResultForOpenNetwork(ScanResult scanResult) { 78 return !(isScanResultForWepNetwork(scanResult) || isScanResultForPskNetwork(scanResult) 79 || isScanResultForEapNetwork(scanResult)); 80 } 81 82 /** 83 * Helper method to quote the SSID in Scan result to use for comparing/filling SSID stored in 84 * WifiConfiguration object. 85 */ 86 @VisibleForTesting 87 public static String createQuotedSSID(String ssid) { 88 return "\"" + ssid + "\""; 89 } 90 91 /** 92 * Checks if the provided |scanResult| match with the provided |config|. Essentially checks 93 * if the network config and scan result have the same SSID and encryption type. 94 */ 95 public static boolean doesScanResultMatchWithNetwork( 96 ScanResult scanResult, WifiConfiguration config) { 97 // Add the double quotes to the scan result SSID for comparison with the network configs. 98 String configSSID = createQuotedSSID(scanResult.SSID); 99 if (TextUtils.equals(config.SSID, configSSID)) { 100 if (ScanResultUtil.isScanResultForPskNetwork(scanResult) 101 && WifiConfigurationUtil.isConfigForPskNetwork(config)) { 102 return true; 103 } 104 if (ScanResultUtil.isScanResultForEapNetwork(scanResult) 105 && WifiConfigurationUtil.isConfigForEapNetwork(config)) { 106 return true; 107 } 108 if (ScanResultUtil.isScanResultForWepNetwork(scanResult) 109 && WifiConfigurationUtil.isConfigForWepNetwork(config)) { 110 return true; 111 } 112 if (ScanResultUtil.isScanResultForOpenNetwork(scanResult) 113 && WifiConfigurationUtil.isConfigForOpenNetwork(config)) { 114 return true; 115 } 116 } 117 return false; 118 } 119 120 /** 121 * Creates a network configuration object using the provided |scanResult|. 122 * This is used to create ephemeral network configurations. 123 */ 124 public static WifiConfiguration createNetworkFromScanResult(ScanResult scanResult) { 125 WifiConfiguration config = new WifiConfiguration(); 126 config.SSID = createQuotedSSID(scanResult.SSID); 127 setAllowedKeyManagementFromScanResult(scanResult, config); 128 return config; 129 } 130 131 /** 132 * Sets the {@link WifiConfiguration#allowedKeyManagement} field on the given 133 * {@link WifiConfiguration} based on its corresponding {@link ScanResult}. 134 */ 135 public static void setAllowedKeyManagementFromScanResult(ScanResult scanResult, 136 WifiConfiguration config) { 137 if (isScanResultForPskNetwork(scanResult)) { 138 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); 139 } else if (isScanResultForEapNetwork(scanResult)) { 140 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); 141 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); 142 } else if (isScanResultForWepNetwork(scanResult)) { 143 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 144 config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); 145 config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); 146 } else { 147 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 148 } 149 } 150 } 151