1f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/* 262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * Copyright (C) 2014 The Android Open Source Project 3f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 4f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Licensed under the Apache License, Version 2.0 (the "License"); 5f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * you may not use this file except in compliance with the License. 6f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * You may obtain a copy of the License at 7f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 8f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * http://www.apache.org/licenses/LICENSE-2.0 9f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 10f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Unless required by applicable law or agreed to in writing, software 11f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * distributed under the License is distributed on an "AS IS" BASIS, 12f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * See the License for the specific language governing permissions and 14f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * limitations under the License. 15f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 16f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepackage com.android.server.wifi; 18f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 19f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.content.Context; 20f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkKey; 21f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkScoreManager; 220c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport android.net.WifiKey; 2377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.ScanResult; 2477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.WifiConfiguration; 258639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiConfiguration.KeyMgmt; 2677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.WifiConnectionStatistics; 27f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalleimport android.os.Process; 2877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.provider.Settings; 29c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalleimport android.text.TextUtils; 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log; 31e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalleimport android.os.SystemClock; 32f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 3377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.io.BufferedReader; 3477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.io.IOException; 3577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.io.StringReader; 360c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.ArrayList; 3777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Arrays; 38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 3977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Iterator; 40f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 41f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 42f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 43f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 44f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 45f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 46f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 47f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 48f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 50f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 51f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 53f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 54f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 56f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 57f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 58f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 5931891afce40b903ada9b24ec12e3648ae6aa27b2Jan Nordqvist private static boolean DBG = false; 60ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 62f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 63c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle public static int mScanResultMaximumAge = 40000; /* milliseconds unit */ 64833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle public static int mScanResultAutoJoinAge = 5000; /* milliseconds unit */ 65c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 66453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 67f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande private final HashMap<String, ScanDetail> scanResultCache = new HashMap<>(); 69f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 70c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle private WifiConnectionStatistics mWifiConnectionStatistics; 71c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 72dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle /** 73dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * Whether to allow connections to untrusted networks. 74dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle */ 758639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean mAllowUntrustedConnections = false; 768639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 77c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /* For debug purpose only: if the scored override a score */ 78c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle boolean didOverride = false; 79c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 80931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose the non-auth failure blacklisting after 8 hours 814dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListHardMilli = 1000 * 60 * 60 * 8; 82931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose some temporary blacklisting after 30 minutes 834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListSoftMilli = 1000 * 60 * 30; 8427355a942653264388e909a4276196ee63e57811vandwalle 85dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle /** 86dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * @see android.provider.Settings.Global#WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS 87dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle */ 8816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private static final long DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS = 1000 * 60; // 1 minute 8916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 90b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_IDLE = 0; 91b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_ROAMING = 1; 92b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_EXTENDED_ROAMING = 2; 93b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3; 94b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 9597b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle public static final int HIGH_THRESHOLD_MODIFIER = 5; 9697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle 9787df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle public static final int MAX_RSSI_DELTA = 50; 9887df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle 991ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // Below are AutoJoin wide parameters indicating if we should be aggressive before joining 1001ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // weak network. Note that we cannot join weak network that are going to be marked as unanted by 1011ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // ConnectivityService because this will trigger link flapping. 1021ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 1031ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * There was a non-blacklisted configuration that we bailed from because of a weak signal 1041ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 1051ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle boolean didBailDueToWeakRssi = false; 1061ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 1071ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * number of time we consecutively bailed out of an eligible network because its signal 1081ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * was too weak 1091ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 1101ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int weakRssiBailCount = 0; 1111ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 112f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 113c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle WifiConnectionStatistics st, WifiNative n) { 114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 115f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 119c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics = st; 12021bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle scoreManager = 12121bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 124f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 125f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 126f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 128f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 131f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 132f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 133f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 136ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 137dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (verbose > 0) { 138abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = true; 139ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 140ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 141abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = false; 142ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 143ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 144ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 145ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 146931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 147931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Flush out scan results older than mScanResultMaximumAge 148931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 149f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 150f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 151931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle delay = mScanResultMaximumAge; // Something sane 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 153b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long milli = System.currentTimeMillis(); 154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 155f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 159dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle Iterator<HashMap.Entry<String, ScanDetail>> iter = scanResultCache.entrySet().iterator(); 160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 161dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle HashMap.Entry<String, ScanDetail> entry = iter.next(); 16225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanDetail scanDetail = entry.getValue(); 16325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if ((scanDetail.getSeen() + delay) < milli) { 164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 166f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 167f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 169ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 170d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande void averageRssiAndRemoveFromCache(ScanResult result) { 171d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // Fetch the previous instance for this result 17225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanDetail sd = scanResultCache.get(result.BSSID); 17325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (sd != null) { 17425ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult sr = sd.getScanResult(); 175d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 176d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande && result.level == 0 177d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande && sr.level < -20) { 178d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // A 'zero' RSSI reading is most likely a chip problem which returns 179d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // an unknown RSSI, hence ignore it 180d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande result.level = sr.level; 181ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 182ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 183d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // If there was a previous cache result for this BSSID, average the RSSI values 184d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge); 185ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 186d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // Remove the previous Scan Result - this is not necessary 187d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande scanResultCache.remove(result.BSSID); 188d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } else if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 && result.level == 0) { 189d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // A 'zero' RSSI reading is most likely a chip problem which returns 190d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // an unknown RSSI, hence initialize it to a sane value 191d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande result.level = mWifiConfigStore.scanResultRssiLevelPatchUp; 192ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 193ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 194ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 195d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande void addToUnscoredNetworks(ScanResult result, List<NetworkKey> unknownScanResults) { 196d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande WifiKey wkey; 197d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // Quoted SSIDs are the only one valid at this stage 198d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande try { 199d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 200d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } catch (IllegalArgumentException e) { 201d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID + 202d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande "] ->skipping this network"); 203d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande wkey = null; 204d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 205d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (wkey != null) { 206d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande NetworkKey nkey = new NetworkKey(wkey); 207d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande //if we don't know this scan result then request a score from the scorer 208d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande unknownScanResults.add(nkey); 209ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 210d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (VDBG) { 211d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande String cap = ""; 212d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (result.capabilities != null) 213d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande cap = result.capabilities; 214d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande logDbg(result.SSID + " " + result.BSSID + " rssi=" 2150510c350db16f6bd2930f0a5ace483efbfa681d5Pierre Vandwalle + result.level + " cap " + cap + " tsf " + result.timestamp + " is not scored"); 216ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 217ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 218ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 21977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int addToScanCache(List<ScanDetail> scanList) { 220be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown = 0; // Record number of scan results we knew about 221be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiConfiguration associatedConfig = null; 2227b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle boolean didAssociate = false; 2238242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 224f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 2250c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 2260c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 227dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle for (ScanDetail scanDetail : scanList) { 22877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ScanResult result = scanDetail.getScanResult(); 2291fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (result.SSID == null) continue; 230c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 231e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle if (VDBG) { 232e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle logDbg(" addToScanCache " + result.SSID + " " + result.BSSID 233e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle + " tsf=" + result.timestamp 234cb59612d2af82044ee74e8f595c9a40498db14b4Pierre Vandwalle + " now= " + now + " uptime=" + SystemClock.uptimeMillis() 235cb59612d2af82044ee74e8f595c9a40498db14b4Pierre Vandwalle + " elapsed=" + SystemClock.elapsedRealtime()); 2360510c350db16f6bd2930f0a5ace483efbfa681d5Pierre Vandwalle } 2370510c350db16f6bd2930f0a5ace483efbfa681d5Pierre Vandwalle 238c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Make sure we record the last time we saw this result 23925ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande scanDetail.setSeen(); 240f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 241d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande averageRssiAndRemoveFromCache(result); 242e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 243e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 244d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande addToUnscoredNetworks(result, unknownScanResults); 2450c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 246e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 2477b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 2487b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 2497b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 250e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 251e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 2527b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is scored : " + score); 2530c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 254f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 255f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 256e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // scanResultCache.put(result.BSSID, new ScanResult(result)); 25725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande scanResultCache.put(result.BSSID, scanDetail); 258be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // Add this BSSID to the scanResultCache of a Saved WifiConfiguration 259d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande didAssociate = mWifiConfigStore.updateSavedNetworkHistory(scanDetail); 260f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 261be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // If not successful, try to associate this BSSID to an existing Saved WifiConfiguration 2627b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (!didAssociate) { 263be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // We couldn't associate the scan result to a Saved WifiConfiguration 264c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Hence it is untrusted 265c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.untrusted = true; 2660d616ef3bf635dff8722e064c0be842676390ed8vandwalle } else { 2670d616ef3bf635dff8722e064c0be842676390ed8vandwalle // If the scan result has been blacklisted fir 18 hours -> unblacklist 2680d616ef3bf635dff8722e064c0be842676390ed8vandwalle if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { 2690d616ef3bf635dff8722e064c0be842676390ed8vandwalle result.setAutoJoinStatus(ScanResult.ENABLED); 2700d616ef3bf635dff8722e064c0be842676390ed8vandwalle } 271f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2727b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (didAssociate) { 273be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown++; 274dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle result.isAutoJoinCandidate++; 275a0708b09ad17b086c008ab100aec7143d7613c80vandwalle } else { 276a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate = 0; 277be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 278f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2790c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 2800c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 2810c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 2820c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 283931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Kick the score manager, we will get updated scores asynchronously 2840c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 2850c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 286be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 287f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 288f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 289f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 2900888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle logDbg(message, false); 291ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 292ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 293ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 294ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 29533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande Log.d(TAG, message + " stack:" 296ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 297ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 298ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 299ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 300ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 30133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande Log.d(TAG, message); 302ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 303f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 304f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 305931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Called directly from WifiStateMachine 306be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int newSupplicantResults(boolean doAutoJoin) { 307be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown; 30877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist List<ScanDetail> scanList = mWifiStateMachine.getScanResultsListNoCopyUnsync(); 309be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown = addToScanCache(scanList); 310f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 311be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle if (DBG) { 312be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) 313dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " known=" + numScanResultsKnown + " " 314dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + doAutoJoin); 315be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 3167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (doAutoJoin) { 3177806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle attemptAutoJoin(); 3187806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 319005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 320be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 321f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 322f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 323f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 324931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 325931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Not used at the moment 326f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 327f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 328f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 329f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 330f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 331f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 33277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist List<ScanDetail> scanList = null;//mWifiScanner.syncGetScanResultsList(); 333f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 334f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 335f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 336f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 337f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 338005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 339f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 340f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 341931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 342dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * network link quality changed, called directly from WifiTrafficPoller, 343931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * or by listening to Link Quality intent 344931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 345f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 346f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 347f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 348f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 349931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 350f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 351f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 352f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 353f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 354b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * Negatve return values from this functions are meaningless per se, just trying to 355e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle * keep them distinct for debug purpose (i.e. -1, -2 etc...) 356931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 357e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle private int compareNetwork(WifiConfiguration candidate, 358e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String lastSelectedConfiguration) { 359b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (candidate == null) 360b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -3; 361b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 362f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 363b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentNetwork == null) { 364c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Return any absurdly high score, if we are not connected there is no current 365c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // network to... 366dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle return 1000; 367b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 368f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 369f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 370b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -2; 371f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 372f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 373b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (DBG) { 374e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("compareNetwork will compare " + candidate.configKey() 375e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " with current " + currentNetwork.configKey()); 376b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 377833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 378e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 379e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 380e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 381e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // enableNetwork with disableOthers=true WifiManager API 382e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // As this is a direct user choice, we strongly prefer this configuration, 383e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // hence give +/-100 384e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if ((lastSelectedConfiguration != null) 385e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && currentNetwork.configKey().equals(lastSelectedConfiguration)) { 386e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // currentNetwork is the last selected configuration, 387e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 388e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 389e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by reducing order by -100 390e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order - 100; 391dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 392e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers -100 " + currentNetwork.configKey() 393e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + candidate.configKey() 394e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 395e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 396e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 397e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } else if ((lastSelectedConfiguration != null) 398e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 399e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // candidate is the last selected configuration, 400e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 401e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 402e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by increasing order by +100 403e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order + 100; 404dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 405e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers +100 " + candidate.configKey() 406e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + currentNetwork.configKey() 407e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 408e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 409e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 410e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 411e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 412ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle return order; 413f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 414f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 415ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 416ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 417ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 418ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 419ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 420ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 42162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 422ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 423ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 424dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * @param connect : if the update includes a connect 425931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 42662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 427f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 428f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 429c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + " no selected configuration!"); 430f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 431f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 432f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 433e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 434c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + 435c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle " no SSID in selected configuration!"); 436e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 437e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 438e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 43962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 440931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable autojoin for this network, 44162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 44227355a942653264388e909a4276196ee63e57811vandwalle selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 44362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 444e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle selected.dirty = true; 44562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 447992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG && userTriggered) { 448f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 449ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 450f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 451992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(selected.connectChoices.size()) 452992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 453f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 454ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 455992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(netId) 456992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 457f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 458f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 459f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 460ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 461ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 4622451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice = 0; 463c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int size = 0; 4649f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 4659f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // Reset the triggered disabled count, because user wanted to connect to this 4669f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // configuration, and we were not. 4679f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableLowRSSI = 0; 4689f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableBadRSSI = 0; 4699f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableNotHighRSSI = 0; 4709f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredJoinAttempts++; 4719f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 47262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 47362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 474c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (networks != null) size = networks.size(); 475c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory found " + size + " networks"); 47662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 47762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 478992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG) { 479992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle logDbg("updateConfigurationHistory got " + config.SSID + " nid=" 480992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(config.networkId)); 481992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 482f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 48362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 484ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 48562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 48662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 487f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 48887df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle // If the selection was made while config was visible with reasonably good RSSI 48987df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle // then register the user preference, else ignore 49087df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle if (config.visibility == null || 49187df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle (config.visibility.rssi24 < mWifiConfigStore.thresholdBadRssi24.get() 49287df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle && config.visibility.rssi5 < mWifiConfigStore.thresholdBadRssi5.get()) 49387df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle ) { 49487df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle continue; 49562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 496f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 49787df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle choice = MAX_RSSI_DELTA + 10; // Make sure the choice overrides the RSSI diff 49887df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle 499931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // The selected configuration was preferred over a recently seen config 500931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // hence remember the user's choice: 501931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // add the recently seen config to the selected's connectChoices array 502ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 503ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (selected.connectChoices == null) { 504ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle selected.connectChoices = new HashMap<String, Integer>(); 505ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 506ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 507ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory add a choice " + selected.configKey(true) 5080888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle + " over " + config.configKey(true) 5092451dbcc4f9641df188326215b204b798eb70c46vandwalle + " choice " + Integer.toString(choice)); 510cf5b8eb8a08c45bd4a82f1f4bb789c8a1b08744fvandwalle 5112f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Add the visible config to the selected's connect choice list 5122f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle selected.connectChoices.put(config.configKey(true), choice); 513f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 51462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 515ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 516ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 51762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 518ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 519931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected from the recently seen config's connectChoice list 52062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 5210888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 5220888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (selected.linkedConfigurations != null) { 523dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle // Remove the selected's linked configuration from the 524dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle // recently seen config's connectChoice list 525dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle for (String key : selected.linkedConfigurations.keySet()) { 526dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle config.connectChoices.remove(key); 527dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 5280888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 52962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 530ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 531ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 532dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle // We haven't found the configuration that the user just selected in our 533dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle // scan cache. 534dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle // In that case we will need a new scan before attempting to connect to this 535dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle // configuration anyhow and thus we can process the scan results then. 536dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 537dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + selected.configKey()); 53862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 539f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 54062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 54162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 542ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 54362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 54462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 545f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 546f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 547992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle 548931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // TODO: write only if something changed 549992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (userTriggered || connect) { 550005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 551992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 552f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 553f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 55421d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle int getConnectChoice(WifiConfiguration source, WifiConfiguration target, boolean strict) { 55521d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle int choice = 0; 5562451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source == null || target == null) { 5572451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 558f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 559f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5602451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source.connectChoices != null 5612451dbcc4f9641df188326215b204b798eb70c46vandwalle && source.connectChoices.containsKey(target.configKey(true))) { 562a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle Integer val = source.connectChoices.get(target.configKey(true)); 563a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle if (val != null) { 564a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle choice = val; 565a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle } 5662451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (source.linkedConfigurations != null) { 567f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 568f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 569f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 570f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 571a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle Integer val = config.connectChoices.get(target.configKey(true)); 572a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle if (val != null) { 573a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle choice = val; 574a20305612380c956fa84b1e80523eb7719f62fd1Pierre Vandwalle } 575f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 576f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 577f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 5782451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5792451dbcc4f9641df188326215b204b798eb70c46vandwalle 58021d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (!strict && choice == 0) { 58133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande // We didn't find the connect choice; fallback to some default choices 58233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande int sourceScore = getSecurityScore(source); 58333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande int targetScore = getSecurityScore(target); 5848eefaf2c281b44fb7a4d951ba587f447800c4b4fVinit Deshpande choice = sourceScore - targetScore; 58533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande } 58633f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande 58733f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande return choice; 5882451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5892451dbcc4f9641df188326215b204b798eb70c46vandwalle 59033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande int compareWifiConfigurationsFromVisibility(WifiConfiguration.Visibility a, int aRssiBoost, 591dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle String dbgA, WifiConfiguration.Visibility b, int bRssiBoost, String dbgB) { 5922451dbcc4f9641df188326215b204b798eb70c46vandwalle 593815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int aRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) 594815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int bRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) 595815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 596815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int aScore = 0; 597815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int bScore = 0; 598815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 599815788ba7838fc54310baed3deb9b95548e0ce69vandwalle boolean aPrefers5GHz = false; 600815788ba7838fc54310baed3deb9b95548e0ce69vandwalle boolean bPrefers5GHz = false; 6014dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 6022451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 603815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * Calculate a boost to apply to RSSI value of configuration we want to join on 5GHz: 604815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * Boost RSSI value of 5GHz bands iff the base value is better than threshold, 605815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * penalize the RSSI value of 5GHz band iff the base value is lower than threshold 6062451dbcc4f9641df188326215b204b798eb70c46vandwalle * This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas 6072451dbcc4f9641df188326215b204b798eb70c46vandwalle * we prefer 2.4GHz otherwise. 6082451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 60933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aRssiBoost5 = rssiBoostFrom5GHzRssi(a.rssi5, dbgA + "->"); 61033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bRssiBoost5 = rssiBoostFrom5GHzRssi(b.rssi5, dbgB + "->"); 6112451dbcc4f9641df188326215b204b798eb70c46vandwalle 612815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for a 61333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (a.rssi5 + aRssiBoost5 > a.rssi24) { 6142451dbcc4f9641df188326215b204b798eb70c46vandwalle // Prefer a's 5GHz 615815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aPrefers5GHz = true; 616815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 617815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 618815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for b 61933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (b.rssi5 + bRssiBoost5 > b.rssi24) { 620815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Prefer b's 5GHz 621815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bPrefers5GHz = true; 622815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 623815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 624815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (aPrefers5GHz) { 625815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (bPrefers5GHz) { 626815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either 627815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // one, but directly compare the RSSI values, this improves stability, 628815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // since the 5GHz RSSI boost can introduce large fluctuations 62933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aScore = a.rssi5 + aRssiBoost; 630815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 631815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only a is on 5GHz, then apply the 5GHz preference boost to a 63233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aScore = a.rssi5 + aRssiBoost + aRssiBoost5; 633815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 6342451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 63533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aScore = a.rssi24 + aRssiBoost; 636f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 6372451dbcc4f9641df188326215b204b798eb70c46vandwalle 638815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (bPrefers5GHz) { 639815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (aPrefers5GHz) { 640815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either 641815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // one, but directly compare the RSSI values, this improves stability, 642815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // since the 5GHz RSSI boost can introduce large fluctuations 64333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bScore = b.rssi5 + bRssiBoost; 644815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 645815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only b is on 5GHz, then apply the 5GHz preference boost to b 64633f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bScore = b.rssi5 + bRssiBoost + bRssiBoost5; 647815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 648815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 64933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bScore = b.rssi24 + bRssiBoost; 650815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 65133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande 652815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (VDBG) { 65333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande logDbg(" " + dbgA + " is5=" + aPrefers5GHz + " score=" + aScore 65433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande + " " + dbgB + " is5=" + bPrefers5GHz + " score=" + bScore); 655815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 656f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 657f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle // Debug only, record RSSI comparison parameters 65833f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (a != null) { 65933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.score = aScore; 66033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.currentNetworkBoost = aRssiBoost; 66133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.bandPreferenceBoost = aRssiBoost5; 662f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 66333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (b != null) { 66433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.score = bScore; 66533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.currentNetworkBoost = bRssiBoost; 66633f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.bandPreferenceBoost = bRssiBoost5; 667f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 668f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 669815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Compare a and b 670815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If a score is higher then a > b and the order is descending (negative) 671815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If b score is higher then a < b and the order is ascending (positive) 672815788ba7838fc54310baed3deb9b95548e0ce69vandwalle return bScore - aScore; 673f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 674f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6752451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50] 6762451dbcc4f9641df188326215b204b798eb70c46vandwalle // The result represents "approximately" an RSSI difference measured in dBM 6772451dbcc4f9641df188326215b204b798eb70c46vandwalle // Adjusted with various parameters: 6782451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) current network gets a +15 boost 6792451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) 5GHz signal, if they are strong enough, get a +15 or +25 boost, representing the 6802451dbcc4f9641df188326215b204b798eb70c46vandwalle // fact that at short range we prefer 5GHz band as it is cleaner of interference and 6812451dbcc4f9641df188326215b204b798eb70c46vandwalle // provides for wider channels 6822451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b, 6832451dbcc4f9641df188326215b204b798eb70c46vandwalle String currentConfiguration) { 684f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 6852451dbcc4f9641df188326215b204b798eb70c46vandwalle 6862451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost used so as to favor current config 6872451dbcc4f9641df188326215b204b798eb70c46vandwalle int aRssiBoost = 0; 6882451dbcc4f9641df188326215b204b798eb70c46vandwalle int bRssiBoost = 0; 6892451dbcc4f9641df188326215b204b798eb70c46vandwalle 6902451dbcc4f9641df188326215b204b798eb70c46vandwalle // Retrieve the visibility 691f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 692f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 693f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 6942451dbcc4f9641df188326215b204b798eb70c46vandwalle // Error visibility wasn't set 695b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations NULL band status!"); 696f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 697f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 6982451dbcc4f9641df188326215b204b798eb70c46vandwalle 6992451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis, boost RSSI of current configuration 7002451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != currentConfiguration) { 7012451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(currentConfiguration)) { 70293a1fddee50a244d31036cddae6b7db6630fd93dvandwalle aRssiBoost = mWifiConfigStore.currentNetworkBoost; 7032451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(currentConfiguration)) { 70493a1fddee50a244d31036cddae6b7db6630fd93dvandwalle bRssiBoost = mWifiConfigStore.currentNetworkBoost; 7052451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7062451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7072451dbcc4f9641df188326215b204b798eb70c46vandwalle 708dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 709b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI: " + a.configKey() 710dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " rssi=" + Integer.toString(astatus.rssi24) 711dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + "," + Integer.toString(astatus.rssi5) 712dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " boost=" + Integer.toString(aRssiBoost) 713dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " " + b.configKey() + " rssi=" 714dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + Integer.toString(bstatus.rssi24) + "," 715dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + Integer.toString(bstatus.rssi5) 716dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " boost=" + Integer.toString(bRssiBoost) 7172451dbcc4f9641df188326215b204b798eb70c46vandwalle ); 718f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7192451dbcc4f9641df188326215b204b798eb70c46vandwalle 72033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande order = compareWifiConfigurationsFromVisibility( 72133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.visibility, aRssiBoost, a.configKey(), 72233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.visibility, bRssiBoost, b.configKey()); 7232451dbcc4f9641df188326215b204b798eb70c46vandwalle 72487df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle // Normalize the order to [-50, +50] = [ -MAX_RSSI_DELTA, MAX_RSSI_DELTA] 72587df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle if (order > MAX_RSSI_DELTA) order = MAX_RSSI_DELTA; 72687df79e235c64f7062d0c50658fe1999b1225435Pierre Vandwalle else if (order < -MAX_RSSI_DELTA) order = -MAX_RSSI_DELTA; 7272451dbcc4f9641df188326215b204b798eb70c46vandwalle 7282451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 7292451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 7302451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 0) { 7312451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; // Ascending 7322451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < 0) { 7332451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; // Descending 7342451dbcc4f9641df188326215b204b798eb70c46vandwalle } 735b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI " + a.configKey() 7362451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 7372451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 7382451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 7392451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 7402451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 7412451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 7422451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 7432451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 7442451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 7452451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + order); 7462451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7472451dbcc4f9641df188326215b204b798eb70c46vandwalle 748f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 749f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 750f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 751833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /** 752833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * b/18490330 only use scorer for untrusted networks 753dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 754dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * int compareWifiConfigurationsWithScorer(WifiConfiguration a, WifiConfiguration b) { 755dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 756dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * boolean aIsActive = false; 757dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * boolean bIsActive = false; 758dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 759dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * // Apply Hysteresis : boost RSSI of current configuration before 760dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * // looking up the score 761dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * if (null != mCurrentConfigurationKey) { 762dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * if (a.configKey().equals(mCurrentConfigurationKey)) { 763dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * aIsActive = true; 764dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } else if (b.configKey().equals(mCurrentConfigurationKey)) { 765dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * bIsActive = true; 766dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 767dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 768dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * int scoreA = getConfigNetworkScore(a, mScanResultAutoJoinAge, aIsActive); 769dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * int scoreB = getConfigNetworkScore(b, mScanResultAutoJoinAge, bIsActive); 770dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 771dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * // Both configurations need to have a score for the scorer to be used 772dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * // ...and the scores need to be different:-) 773dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * if (scoreA == WifiNetworkScoreCache.INVALID_NETWORK_SCORE 774dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * || scoreB == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 775dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * if (VDBG) { 776dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * logDbg(" compareWifiConfigurationsWithScorer no-scores: " 777dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + a.configKey() 778dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + " " 779dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + b.configKey()); 780dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 781dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * return 0; 782dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 783dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 784dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * if (VDBG) { 785dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * String prefer = " = "; 786dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * if (scoreA < scoreB) { 787dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * prefer = " < "; 788dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } if (scoreA > scoreB) { 789dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * prefer = " > "; 790dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 791dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * logDbg(" compareWifiConfigurationsWithScorer " + a.configKey() 792dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + " rssi=(" + a.visibility.rssi24 793dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + "," + a.visibility.rssi5 794dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + ") num=(" + a.visibility.num24 795dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + "," + a.visibility.num5 + ")" 796dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + " sc=" + scoreA 797dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + prefer + b.configKey() 798dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + " rssi=(" + b.visibility.rssi24 799dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + "," + b.visibility.rssi5 800dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + ") num=(" + b.visibility.num24 801dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + "," + b.visibility.num5 + ")" 802dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + " sc=" + scoreB 803dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * + " -> " + Integer.toString(scoreB - scoreA)); 804dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 805dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 806dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * // If scoreA > scoreB, the comparison is descending hence the return value is negative 807dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * return scoreB - scoreA; 808dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * } 809833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 8102451dbcc4f9641df188326215b204b798eb70c46vandwalle 811d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande int getSecurityScore(WifiConfiguration config) { 812d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 813d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (TextUtils.isEmpty(config.SSID) == false) { 814d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) 815d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande || config.allowedKeyManagement.get(KeyMgmt.WPA_PSK) 816d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande || config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 817d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* enterprise or PSK networks get highest score */ 818d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 100; 819d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } else if (config.allowedKeyManagement.get(KeyMgmt.NONE)) { 820d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* open networks have lowest score */ 821d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 33; 822d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 823d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } else if (TextUtils.isEmpty(config.FQDN) == false) { 824d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* passpoint networks have medium preference */ 825d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 66; 826d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 827d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 828d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* bad network */ 829d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 0; 830d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 831d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 832f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 833f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 834f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 835f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 836453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 837453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 838453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 8392451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((a.linkedConfigurations.get(b.configKey(true)) != null) 8402451dbcc4f9641df188326215b204b798eb70c46vandwalle && (b.linkedConfigurations.get(a.configKey(true)) != null)) { 841f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 842f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 843f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 844f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 845f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 846f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 847b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + b.configKey() 848453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 849f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 850931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return 1; // b is of higher priority - ascending 851f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 852f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 853f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 854b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + a.configKey() 855453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 856f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 857931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return -1; // a is of higher priority - descending 858f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 859f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8602451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply RSSI, in the range [-5, +5] 8612451dbcc4f9641df188326215b204b798eb70c46vandwalle // after band adjustment, +n difference roughly corresponds to +10xn dBm 8622451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + compareWifiConfigurationsRSSI(a, b, mCurrentConfigurationKey); 863f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8642451dbcc4f9641df188326215b204b798eb70c46vandwalle // If the configurations are not linked, compare by user's choice, only a 8652451dbcc4f9641df188326215b204b798eb70c46vandwalle // very high RSSI difference can then override the choice 8662451dbcc4f9641df188326215b204b798eb70c46vandwalle if (!linked) { 8672451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice; 868f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 86921d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle choice = getConnectChoice(a, b, false); 8702451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 871931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 8722451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - choice; 873f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 874b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + a.configKey() 875453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 876b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " due to user choice of " + choice 877b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order -> " + Integer.toString(order)); 878f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 879f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility != null) { 880f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceBoost = choice; 881f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceConfig = b.configKey(); 882f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 8832451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8842451dbcc4f9641df188326215b204b798eb70c46vandwalle 88521d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle choice = getConnectChoice(b, a, false); 8862451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 887931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 8882451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + choice; 8894dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 890b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + b.configKey() + " over " 891b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + a.configKey() + " due to user choice of " + choice 892b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order ->" + Integer.toString(order)); 893f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 894f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (b.visibility != null) { 895f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceBoost = choice; 896f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceConfig = a.configKey(); 897f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 898f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 899f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 900ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 901f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 902931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // We don't know anything - pick the last seen i.e. K behavior 903931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // we should do this only for recently picked configurations 904f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 905931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 9062451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 907b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers -1 " + a.configKey() + " over " 908453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 909f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 910f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 911f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 912f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 913931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 9142451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 915b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers +1 " + b.configKey() + " over " 916453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 917f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 9182451dbcc4f9641df188326215b204b798eb70c46vandwalle order = 1; 919f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 920f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 921f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 922f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 923931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if (order > 0) { 924f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 925931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } else if (order < 0) { 926f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 927931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } 928f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9292451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 930b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("compareWifiConfigurations: " + a.configKey() + sorder 931453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 932f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 933f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 934f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 935f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 936f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 937c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle boolean isBadCandidate(int rssi5, int rssi24) { 938c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle return (rssi5 < -80 && rssi24 < -90); 939c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 940c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 941833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /* 942c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int compareWifiConfigurationsTop(WifiConfiguration a, WifiConfiguration b) { 943c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int scorerOrder = compareWifiConfigurationsWithScorer(a, b); 944c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int order = compareWifiConfigurations(a, b); 945c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 946c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder * order < 0) { 947b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (VDBG) { 948b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" -> compareWifiConfigurationsTop: " + 949b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle "scorer override " + scorerOrder + " " + order); 950b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 951c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // For debugging purpose, remember that an override happened 952c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // during that autojoin Attempt 953c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = true; 954c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle a.numScorerOverride++; 955c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle b.numScorerOverride++; 956c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 957c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 958c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder != 0) { 959c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If the scorer came up with a result then use the scorer's result, else use 960c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // the order provided by the base comparison function 961c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle order = scorerOrder; 962c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 963c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle return order; 964c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 965833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 966c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 9679f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle public int rssiBoostFrom5GHzRssi(int rssi, String dbg) { 9680eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!mWifiConfigStore.enable5GHzPreference) { 9690eebae7334d6129f7ca1344e4b20199794994358vandwalle return 0; 9700eebae7334d6129f7ca1344e4b20199794994358vandwalle } 971e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 97277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist > mWifiConfigStore.bandPreferenceBoostThreshold5.get()) { 973e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 2 dB for each point 974e67ec726c07410073575473c0f50dc737629f5davandwalle // Start boosting at -65 975e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 20 if above -55 976e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 40 if abore -45 9770eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferenceBoostFactor5 978dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * (rssi - mWifiConfigStore.bandPreferenceBoostThreshold5.get()); 979e67ec726c07410073575473c0f50dc737629f5davandwalle if (boost > 50) { 980815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // 50 dB boost allows jumping from 2.4 to 5GHz 981e67ec726c07410073575473c0f50dc737629f5davandwalle // consistently 982e67ec726c07410073575473c0f50dc737629f5davandwalle boost = 50; 983e67ec726c07410073575473c0f50dc737629f5davandwalle } 9849f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle if (VDBG && dbg != null) { 985f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle logDbg(" " + dbg + ": rssi5 " + rssi + " 5GHz-boost " + boost); 9869f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 987e67ec726c07410073575473c0f50dc737629f5davandwalle return boost; 988e67ec726c07410073575473c0f50dc737629f5davandwalle } 989e67ec726c07410073575473c0f50dc737629f5davandwalle 990e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 99177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist < mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 9920eebae7334d6129f7ca1344e4b20199794994358vandwalle // penalize if < -75 9930eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferencePenaltyFactor5 994dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * (rssi - mWifiConfigStore.bandPreferencePenaltyThreshold5.get()); 9950eebae7334d6129f7ca1344e4b20199794994358vandwalle return boost; 996e67ec726c07410073575473c0f50dc737629f5davandwalle } 997e67ec726c07410073575473c0f50dc737629f5davandwalle return 0; 998e67ec726c07410073575473c0f50dc737629f5davandwalle } 999dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle 1000dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle /** 1001dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * attemptRoam() function implements the core of the same SSID switching algorithm 1002dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 1003dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * Run thru all recent scan result of a WifiConfiguration and select the 1004dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * best one. 1005dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle */ 1006e67ec726c07410073575473c0f50dc737629f5davandwalle public ScanResult attemptRoam(ScanResult a, 1007e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration current, int age, String currentBSSID) { 1008b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current == null) { 1009dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 1010b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam not associated"); 1011b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1012e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 101425ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande 10154d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande ScanDetailCache scanDetailCache = 101625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande mWifiConfigStore.getScanDetailCache(current); 101725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande 101825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (scanDetailCache == null) { 1019dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 1020b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam no scan cache"); 1021b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1022e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10234dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 102425ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (scanDetailCache.size() > 6) { 1025dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 1026c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam scan cache size " 102725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande + scanDetailCache.size() + " --> bail"); 1028b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1029931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Implement same SSID roaming only for configurations 1030c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // that have less than 4 BSSIDs 1031e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10324dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1033b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 10342f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (current.BSSID != null && !current.BSSID.equals("any")) { 1035dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (DBG) { 10362f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("attemptRoam() BSSID is set " 10372f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + current.BSSID + " -> bail"); 1038b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1039e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10414dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1042931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Determine which BSSID we want to associate to, taking account 1043c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // relative strength of 5 and 2.4 GHz BSSIDs 10442451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 10454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 104625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail sd : scanDetailCache.values()) { 104725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult b = sd.getScanResult(); 104897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost5 = 0; 104997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost5 = 0; 105097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost = 0; 105197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost = 0; 105225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if ((sd.getSeen() == 0) || (b.BSSID == null) 105325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande || ((nowMs - sd.getSeen()) > age) 1054e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.autoJoinStatus != ScanResult.ENABLED 1055e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.numIpConfigFailures > 8) { 10564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 10573a2a3d226881cce8a4e511302231d843b0def303vandwalle } 10584dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1059931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Pick first one 10604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (a == null) { 10614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle a = b; 10624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 10634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1065e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (b.numIpConfigFailures < (a.numIpConfigFailures - 1)) { 1066e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // Prefer a BSSID that doesn't have less number of Ip config failures 1067e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptRoam: " 1068dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + b.BSSID + " rssi=" + b.level + " ipfail=" + b.numIpConfigFailures 1069e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + b.frequency 1070e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " > " 1071dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + a.BSSID + " rssi=" + a.level + " ipfail=" + a.numIpConfigFailures 1072e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + a.frequency); 1073e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle a = b; 1074e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle continue; 1075e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1076e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 10772451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply hysteresis: we favor the currentBSSID by giving it a boost 10787806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(b.BSSID)) { 1079931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 108077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (b.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 10810eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1082c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 10830eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1084c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 10854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10867806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(a.BSSID)) { 108777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (a.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 1088931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 10890eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1090c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 10910eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1092c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 10934dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10942451dbcc4f9641df188326215b204b798eb70c46vandwalle 109597b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve 10962451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost the BSSID if it is on 5GHz, above a threshold 10972451dbcc4f9641df188326215b204b798eb70c46vandwalle // But penalize it if it is on 5GHz and below threshold 109897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // 109997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // With he current threshold values, 5GHz network with RSSI above -55 110097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Are given a boost of 30DB which is enough to overcome the current BSSID 110197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases 11029f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // 11039f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // The "current BSSID" Boost must be added to the BSSID's level so as to introduce\ 11049f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // soem amount of hysteresis 1105e67ec726c07410073575473c0f50dc737629f5davandwalle if (b.is5GHz()) { 11069f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.level + bRssiBoost, b.BSSID); 11074dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1108e67ec726c07410073575473c0f50dc737629f5davandwalle if (a.is5GHz()) { 11099f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.level + aRssiBoost, a.BSSID); 11104dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11114dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1112dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 1113c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle String comp = " < "; 1114dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level + aRssiBoost + aRssiBoost5) { 1115c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle comp = " > "; 1116c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 11174dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptRoam: " 1118c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost) 111997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency 112097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + comp 1121c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost) 1122c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency); 1123c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 1124c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle 11252451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare the RSSIs after applying the hysteresis boost and the 5GHz 11262451dbcc4f9641df188326215b204b798eb70c46vandwalle // boost if applicable 1127dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level + aRssiBoost + aRssiBoost5) { 1128931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // b is the better BSSID 1129c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle a = b; 11304dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11314dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11323a2a3d226881cce8a4e511302231d843b0def303vandwalle if (a != null) { 1133dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 11347806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle StringBuilder sb = new StringBuilder(); 1135e67ec726c07410073575473c0f50dc737629f5davandwalle sb.append("attemptRoam: " + current.configKey() + 1136e67ec726c07410073575473c0f50dc737629f5davandwalle " Found " + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency); 11377806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null) { 11387806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append(" Current: " + currentBSSID); 11397806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 11407806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append("\n"); 11417806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle logDbg(sb.toString()); 11423a2a3d226881cce8a4e511302231d843b0def303vandwalle } 11434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11443a2a3d226881cce8a4e511302231d843b0def303vandwalle return a; 11454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11464dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1147931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 11482451dbcc4f9641df188326215b204b798eb70c46vandwalle * getNetworkScore() 1149dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 11502451dbcc4f9641df188326215b204b798eb70c46vandwalle * if scorer is present, get the network score of a WifiConfiguration 1151dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * <p/> 11522451dbcc4f9641df188326215b204b798eb70c46vandwalle * Note: this should be merge with setVisibility 11532451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11542451dbcc4f9641df188326215b204b798eb70c46vandwalle * @param config 11552451dbcc4f9641df188326215b204b798eb70c46vandwalle * @return score 11562451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 115781c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int getConfigNetworkScore(WifiConfiguration config, int age, boolean isActive) { 11582451dbcc4f9641df188326215b204b798eb70c46vandwalle 11592451dbcc4f9641df188326215b204b798eb70c46vandwalle if (mNetworkScoreCache == null) { 1160e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1161b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1162e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scorer, hence no scores"); 1163e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 11641db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11651db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 116625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande 116725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (mWifiConfigStore.getScanDetailCache(config) == null) { 1168e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1169b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1170e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scan cache"); 1171e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 11721db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11732451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11742451dbcc4f9641df188326215b204b798eb70c46vandwalle 11752451dbcc4f9641df188326215b204b798eb70c46vandwalle // Get current date 11762451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 11772451dbcc4f9641df188326215b204b798eb70c46vandwalle 11781db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle int startScore = -10000; 11791db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle 11802451dbcc4f9641df188326215b204b798eb70c46vandwalle // Run thru all cached scan results 118125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail sd : mWifiConfigStore.getScanDetailCache(config).values()) { 118225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult result = sd.getScanResult(); 118325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if ((nowMs - sd.getSeen()) < age) { 118481c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int sc = mNetworkScoreCache.getNetworkScore(result, isActive); 11851db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (sc > startScore) { 11861db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = sc; 11872451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11882451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11892451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11901db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (startScore == -10000) { 11911db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11921db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 1193e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1194e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (startScore == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 1195b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1196e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no available score"); 1197e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } else { 1198b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 119981c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson + " isActive=" + isActive 1200e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " score = " + Integer.toString(startScore)); 1201e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1202e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1203e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle 12041db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return startScore; 12052451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12062451dbcc4f9641df188326215b204b798eb70c46vandwalle 12072451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 12088639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson * Set whether connections to untrusted connections are allowed. 12098639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson */ 12108639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson void setAllowUntrustedConnections(boolean allow) { 12118639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson boolean changed = mAllowUntrustedConnections != allow; 12128639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson mAllowUntrustedConnections = allow; 12138639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (changed) { 1214005c1ef113192f898499a407dd266393a8d6b076vandwalle // Trigger a scan so as to reattempt autojoin 1215005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiStateMachine.startScanForUntrustedSettingChange(); 12168639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 12178639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 12188639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 12198639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean isOpenNetwork(ScanResult result) { 12208639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson return !result.capabilities.contains("WEP") && 12218639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("PSK") && 12228639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("EAP"); 12238639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 12248639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 122516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private boolean haveRecentlySeenScoredBssid(WifiConfiguration config) { 122616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long ephemeralOutOfRangeTimeoutMs = Settings.Global.getLong( 122716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson mContext.getContentResolver(), 122816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson Settings.Global.WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS, 122916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS); 123016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 123116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Check whether the currently selected network has a score curve. If 123216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // ephemeralOutOfRangeTimeoutMs is <= 0, then this is all we check, and we stop here. 123316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Otherwise, we stop here if the currently selected network has a score. If it doesn't, we 123416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // keep going - it could be that another BSSID is in range (has been seen recently) which 123516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // has a score, even if the one we're immediately connected to doesn't. 1236dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle ScanResult currentScanResult = mWifiStateMachine.getCurrentScanResult(); 1237be4d4bfef88bb0870e1e8bb464c302a2e54bbed4Pierre Vandwalle boolean currentNetworkHasScoreCurve = currentScanResult != null 1238be4d4bfef88bb0870e1e8bb464c302a2e54bbed4Pierre Vandwalle && mNetworkScoreCache.hasScoreCurve(currentScanResult); 123916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (ephemeralOutOfRangeTimeoutMs <= 0 || currentNetworkHasScoreCurve) { 124016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 124116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (currentNetworkHasScoreCurve) { 124216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has a score curve, keeping network: " 124316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson + currentScanResult); 124416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } else { 124516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has no score curve, giving up: " + config.SSID); 124616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 124716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 124816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return currentNetworkHasScoreCurve; 124916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 125016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 125125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (mWifiConfigStore.getScanDetailCache(config) == null 125225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande || mWifiConfigStore.getScanDetailCache(config).isEmpty()) { 125316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 125416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 125516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 125616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long currentTimeMs = System.currentTimeMillis(); 125725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail sd : mWifiConfigStore.getScanDetailCache(config).values()) { 125825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult result = sd.getScanResult(); 125925ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (currentTimeMs > sd.getSeen() 126025ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande && currentTimeMs - sd.getSeen() < ephemeralOutOfRangeTimeoutMs 126116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson && mNetworkScoreCache.hasScoreCurve(result)) { 126216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 126316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Found scored BSSID, keeping network: " + result.BSSID); 126416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 126516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return true; 126616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 126716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 126816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 126916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 127016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("No recently scored BSSID found, giving up connection: " + config.SSID); 127116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 127216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 127316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 127416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 127577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // After WifiStateMachine ask the supplicant to associate or reconnect 127677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // we might still obtain scan results from supplicant 127777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // however the supplicant state in the mWifiInfo and supplicant state tracker 127877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // are updated when we get the supplicant state change message which can be 127977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // processed after the SCAN_RESULT message, so at this point the framework doesn't 128077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // know that supplicant is ASSOCIATING. 128177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // A good fix for this race condition would be for the WifiStateMachine to add 128277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // a new transient state where it expects to get the supplicant message indicating 128377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // that it started the association process and within which critical operations 128477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // like autojoin should be deleted. 128577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 128677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // This transient state would remove the need for the roam Wathchdog which 128777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // basically does that. 128877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 128977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // At the moment, we just query the supplicant state synchronously with the 129077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // mWifiNative.status() command, which allow us to know that 129177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // supplicant has started association process, even though we didnt yet get the 129277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // SUPPLICANT_STATE_CHANGE message. 129377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 129477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final List<String> ASSOC_STATES = Arrays.asList( 129577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "ASSOCIATING", 129677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "ASSOCIATED", 129777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "FOUR_WAY_HANDSHAKE", 129877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "GROUP_KEY_HANDSHAKE"); 129977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 130077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private int getNetID(String wpaStatus) { 130177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (VDBG) { 130277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() status=" + wpaStatus); 130377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 130477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 130577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist try { 130677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int id = WifiConfiguration.INVALID_NETWORK_ID; 130777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String state = null; 130877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist BufferedReader br = new BufferedReader(new StringReader(wpaStatus)); 130977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String line; 1310dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle while ((line = br.readLine()) != null) { 131177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int split = line.indexOf('='); 131277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (split < 0) { 131377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist continue; 131477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 131577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 131677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String name = line.substring(0, split); 131777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (name.equals("id")) { 131877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist try { 1319dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle id = Integer.parseInt(line.substring(split + 1)); 132077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (state != null) { 132177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist break; 132277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 1323dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } catch (NumberFormatException nfe) { 132477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; 132577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 1326dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } else if (name.equals("wpa_state")) { 1327dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle state = line.substring(split + 1); 132877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (ASSOC_STATES.contains(state)) { 132977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; 1330dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } else if (id >= 0) { 133177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist break; 133277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 133377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 133477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 133577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return id; 1336dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } catch (IOException ioe) { 133777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; // Won't happen 133877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 133977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 134077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 134177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private boolean setCurrentConfigurationKey(WifiConfiguration currentConfig, 134277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int supplicantNetId) { 134377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (currentConfig != null) { 134477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (supplicantNetId != currentConfig.networkId 134577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // https://b.corp.google.com/issue?id=16484607 134677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // mark this condition as an error only if the mismatched networkId are valid 134777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID 134877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && currentConfig.networkId != WifiConfiguration.INVALID_NETWORK_ID) { 134977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 135077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(supplicantNetId) + " WifiStateMachine=" 135177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(currentConfig.networkId)); 135277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiStateMachine.disconnectCommand(); 135377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 135477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else if (currentConfig.ephemeral && (!mAllowUntrustedConnections || 135577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist !haveRecentlySeenScoredBssid(currentConfig))) { 135677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // The current connection is untrusted (the framework added it), but we're either 135777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // no longer allowed to connect to such networks, the score has been nullified 135877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // since we connected, or the scored BSSID has gone out of range. 135977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Drop the current connection and perform the rest of autojoin. 136077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network"); 136177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiStateMachine.disconnectCommand(Process.WIFI_UID, 136277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAllowUntrustedConnections ? 1 : 0); 136377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 136477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 136577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCurrentConfigurationKey = currentConfig.configKey(); 136677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return true; 136777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 136877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 136977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // If not invalid, then maybe in the process of associating, skip this attempt 137077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return supplicantNetId == WifiConfiguration.INVALID_NETWORK_ID; 137177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 137277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 137377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 137477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private void updateBlackListStatus(WifiConfiguration config, long now) { 137577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Wait for 5 minutes before reenabling config that have known, 137677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // repeated connection or DHCP failures 137777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE 137877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || config.disableReason 137977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist == WifiConfiguration.DISABLED_ASSOCIATION_REJECT 138077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || config.disableReason 138177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist == WifiConfiguration.DISABLED_AUTH_FAILURE) { 138277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.blackListTimestamp == 0 138377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || (config.blackListTimestamp > now)) { 138477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Sanitize the timestamp 138577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.blackListTimestamp = now; 138677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 138777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if ((now - config.blackListTimestamp) > 138877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.wifiConfigBlacklistMinTimeMilli) { 138977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Re-enable the WifiConfiguration 139077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.status = WifiConfiguration.Status.ENABLED; 139177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 139277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Reset the blacklist condition 139377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numConnectionFailures = 0; 139477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numIpConfigFailures = 0; 139577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numAuthFailures = 0; 139677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 139777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 139877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.dirty = true; 139977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 140077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (VDBG) { 140177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist long delay = mWifiConfigStore.wifiConfigBlacklistMinTimeMilli 140277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist - (now - config.blackListTimestamp); 140377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptautoJoin " + config.configKey() 140477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + " dont unblacklist yet, waiting for " 140577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + delay + " ms"); 140677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Avoid networks disabled because of AUTH failure altogether 141077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (DBG) { 141177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin skip candidate due to auto join status " 141277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(config.autoJoinStatus) + " key " 141377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + config.configKey(true) 141477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + " reason " + config.disableReason); 141577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 141677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 1417dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle 141877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underSoftThreshold(WifiConfiguration config) { 141977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Soft.get() 1420dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Soft.get(); 142177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 142277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 142377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underHardThreshold(WifiConfiguration config) { 142477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Hard.get() 1425dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Hard.get(); 142677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 142777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 142877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underThreshold(WifiConfiguration config, int rssi24, int rssi5) { 142977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < rssi24 && config.visibility.rssi5 < rssi5; 143077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 143177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 14328639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** 1433931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * attemptAutoJoin() function implements the core of the a network switching algorithm 143468fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle * Return false if no acceptable networks were found. 1435931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 143668fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean attemptAutoJoin() { 143768fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean found = false; 1438c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = false; 14391ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = false; 1440b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkSwitchType = AUTO_JOIN_IDLE; 1441e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle int age = mScanResultAutoJoinAge; 14424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 14438242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 14448242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle 14458c9088d11880553458f09377cc60d6eb7e66747bvandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 1446e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle if (lastSelectedConfiguration != null) { 1447e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle age = 14000; 1448e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle } 1449931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reset the currentConfiguration Key, and set it only if WifiStateMachine and 1450453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 1451453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 1452453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 1453453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1454f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 1455931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Obtain the subset of recently seen networks 1456833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle List<WifiConfiguration> list = 1457e3e4fad6e9b2022018a33507e93a39c6446f9916Pierre Vandwalle mWifiConfigStore.getRecentConfiguredNetworks(age, false); 1458f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 1459dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) logDbg("attemptAutoJoin nothing known=" + 146031891afce40b903ada9b24ec12e3648ae6aa27b2Jan Nordqvist mWifiConfigStore.getConfiguredNetworksSize()); 146168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1462f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1463f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1464931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Find the currently connected network: ask the supplicant directly 146577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int supplicantNetId = getNetID(mWifiNative.status(true)); 146649bc8dd35845318cd9bc5ce9064fc1ad33bbece8xinhe 1467ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 14687806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle String conf = ""; 1469b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String last = ""; 14707806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentConfiguration != null) { 1471e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle conf = " current=" + currentConfiguration.configKey(); 1472b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1473b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (lastSelectedConfiguration != null) { 14742f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle last = " last=" + lastSelectedConfiguration; 14757806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 1476ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 1477b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + conf + last 1478b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " ---> suppNetId=" + Integer.toString(supplicantNetId)); 1479ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1480f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 148177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (!setCurrentConfigurationKey(currentConfiguration, supplicantNetId)) { 148277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 1483453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 1484453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1485b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int currentNetId = -1; 1486b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentConfiguration != null) { 1487931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If we are associated to a configuration, it will 1488b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // be compared thru the compareNetwork function 1489b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle currentNetId = currentConfiguration.networkId; 1490b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 1491b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle 1492931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1493931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Run thru all visible configurations without looking at the one we 1494c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle * are currently associated to 14954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * select Best Network candidate from known WifiConfigurations 1496931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1497f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 1498e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 1499b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle continue; 1500e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 1501e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 150277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.autoJoinStatus >= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) { 150377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist updateBlackListStatus(config, now); 1504f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1505f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1506f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1507e487a4648dd41881e754f1224aaedead78a0777dSky Faber if (config.userApproved == WifiConfiguration.USER_PENDING || 1508e487a4648dd41881e754f1224aaedead78a0777dSky Faber config.userApproved == WifiConfiguration.USER_BANNED) { 1509e487a4648dd41881e754f1224aaedead78a0777dSky Faber if (DBG) { 1510e487a4648dd41881e754f1224aaedead78a0777dSky Faber logDbg("attemptAutoJoin skip candidate due to user approval status " 1511e487a4648dd41881e754f1224aaedead78a0777dSky Faber + WifiConfiguration.userApprovedAsString(config.userApproved) + " key " 1512e487a4648dd41881e754f1224aaedead78a0777dSky Faber + config.configKey(true)); 1513e487a4648dd41881e754f1224aaedead78a0777dSky Faber } 1514e487a4648dd41881e754f1224aaedead78a0777dSky Faber continue; 1515e487a4648dd41881e754f1224aaedead78a0777dSky Faber } 1516e487a4648dd41881e754f1224aaedead78a0777dSky Faber 1517931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to un-blacklist based on elapsed time 151827355a942653264388e909a4276196ee63e57811vandwalle if (config.blackListTimestamp > 0) { 151927355a942653264388e909a4276196ee63e57811vandwalle if (now < config.blackListTimestamp) { 1520931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1521931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * looks like there was a change in the system clock since we black listed, and 1522931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * timestamp is not meaningful anymore, hence lose it. 1523931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * this event should be rare enough so that we still want to lose the black list 15242451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 152527355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 152627355a942653264388e909a4276196ee63e57811vandwalle } else { 15274dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now - config.blackListTimestamp) > loseBlackListHardMilli) { 1528931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable it after 18 hours, i.e. next day 152927355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 15304dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) { 1531931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose blacklisting due to bad link 153227355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 8); 153327355a942653264388e909a4276196ee63e57811vandwalle } 153427355a942653264388e909a4276196ee63e57811vandwalle } 153527355a942653264388e909a4276196ee63e57811vandwalle } 153627355a942653264388e909a4276196ee63e57811vandwalle 153777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.visibility == null) { 153877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist continue; 153977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 154077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1541931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to unblacklist based on good visibility 154277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (underSoftThreshold(config)) { 154321d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 154421d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle logDbg("attemptAutoJoin do not unblacklist due to low visibility " + 154521d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle config.configKey() + " status=" + config.autoJoinStatus); 154621d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 154777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else if (underHardThreshold(config)) { 1548931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If the network is simply temporary disabled, don't allow reconnect until 1549931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // RSSI becomes good enough 155027355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 1); 155121d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 155221d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle logDbg("attemptAutoJoin good candidate seen, bumped soft -> status=" + 155321d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle config.configKey() + " status=" + config.autoJoinStatus); 155421d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 155527355a942653264388e909a4276196ee63e57811vandwalle } else { 1556c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 3); 155721d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 155821d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle logDbg("attemptAutoJoin good candidate seen, bumped hard -> status=" + 155921d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle config.configKey() + " status=" + config.autoJoinStatus); 156021d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 156127355a942653264388e909a4276196ee63e57811vandwalle } 156227355a942653264388e909a4276196ee63e57811vandwalle 156327355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 156427355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 1565931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Network is blacklisted, skip 156621d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 156721d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle logDbg("attemptAutoJoin skip blacklisted -> status=" + 156821d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle config.configKey() + " status=" + config.autoJoinStatus); 156921d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 157027355a942653264388e909a4276196ee63e57811vandwalle continue; 157127355a942653264388e909a4276196ee63e57811vandwalle } 1572f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 1573ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 157421bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("attemptAutoJoin skip current candidate " 157521bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle + Integer.toString(currentNetId) 1576ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 1577ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1578f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1579f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1580f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 15810eebae7334d6129f7ca1344e4b20199794994358vandwalle boolean isLastSelected = false; 15820eebae7334d6129f7ca1344e4b20199794994358vandwalle if (lastSelectedConfiguration != null && 15830eebae7334d6129f7ca1344e4b20199794994358vandwalle config.configKey().equals(lastSelectedConfiguration)) { 15840eebae7334d6129f7ca1344e4b20199794994358vandwalle isLastSelected = true; 15850eebae7334d6129f7ca1344e4b20199794994358vandwalle } 15860eebae7334d6129f7ca1344e4b20199794994358vandwalle 15874fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (config.lastRoamingFailure != 0 15884fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && currentConfiguration != null 15894fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && (lastSelectedConfiguration == null 15904fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle || !config.configKey().equals(lastSelectedConfiguration))) { 15914fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // Apply blacklisting for roaming to this config if: 15924fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - the target config had a recent roaming failure 15934fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - we are currently associated 15944fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - the target config is not the last selected 15954fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (now > config.lastRoamingFailure 15964fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && (now - config.lastRoamingFailure) 15974fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle < config.roamingFailureBlackListTimeMilli) { 15984fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (DBG) { 15994fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle logDbg("compareNetwork not switching to " + config.configKey() 16004fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " from current " + currentConfiguration.configKey() 16014fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " because it is blacklisted due to roam failure, " 16024fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " blacklist remain time = " 16034fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + (now - config.lastRoamingFailure) + " ms"); 16044fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 16054fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle continue; 16064fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 16074fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 16084fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle 16091ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount; 161077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (underThreshold(config, 161177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.thresholdInitialAutoJoinAttemptMin24RSSI.get() - boost, 161277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI.get() - boost)) { 161377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 161421d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 161521d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle logDbg("attemptAutoJoin skip due to low visibility " + config.configKey()); 161621d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 16170eebae7334d6129f7ca1344e4b20199794994358vandwalle 1618c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Don't try to autojoin a network that is too far but 1619c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If that configuration is a user's choice however, try anyway 16200eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!isLastSelected) { 16210eebae7334d6129f7ca1344e4b20199794994358vandwalle config.autoJoinBailedDueToLowRssi = true; 16221ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = true; 16238c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 16240eebae7334d6129f7ca1344e4b20199794994358vandwalle } else { 16250eebae7334d6129f7ca1344e4b20199794994358vandwalle // Next time, try to be a bit more aggressive in auto-joining 16260eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.autoJoinUseAggressiveJoinAttemptThreshold 1627dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle < WifiConfiguration.MAX_INITIAL_AUTO_JOIN_RSSI_BOOST 1628dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle && config.autoJoinBailedDueToLowRssi) { 1629dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle config.autoJoinUseAggressiveJoinAttemptThreshold += 4; 16304dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 16318c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 16320eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1633312c60d9779c200e8250b8a7ae32eaea01b08b42Paul Jensen // NOTE: If this condition is updated, update NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN. 1634d30127db46224e45554f8964209221bba8ad41d9vandwalle if (config.numNoInternetAccessReports > 0 1635d30127db46224e45554f8964209221bba8ad41d9vandwalle && !isLastSelected 1636d30127db46224e45554f8964209221bba8ad41d9vandwalle && !config.validatedInternetAccess) { 1637d30127db46224e45554f8964209221bba8ad41d9vandwalle // Avoid autoJoining this network because last time we used it, it didn't 1638d30127db46224e45554f8964209221bba8ad41d9vandwalle // have internet access, and we never manage to validate internet access on this 1639d30127db46224e45554f8964209221bba8ad41d9vandwalle // network configuration 16400eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 1641d30127db46224e45554f8964209221bba8ad41d9vandwalle logDbg("attemptAutoJoin skip candidate due to no InternetAccess " 1642d30127db46224e45554f8964209221bba8ad41d9vandwalle + config.configKey(true) 1643d30127db46224e45554f8964209221bba8ad41d9vandwalle + " num reports " + config.numNoInternetAccessReports); 16449f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 16450eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 16468c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 16478c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1648ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1649e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String cur = ""; 1650e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (candidate != null) { 1651e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle cur = " current candidate " + candidate.configKey(); 1652e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1653e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptAutoJoin trying id=" 1654c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Integer.toString(config.networkId) + " " 1655b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + config.configKey(true) 1656e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " status=" + config.autoJoinStatus 1657e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + cur); 1658ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1659f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1660f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 1661f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1662f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1663dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 1664453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 16654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " with " + config.configKey()); 1666f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 16674d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande 1668833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(candidate, config); 16694d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande if (VDBG) { 16704d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande logDbg("attemptAutoJoin compareWifiConfigurations returned " + order); 16714d381bc39f5263effdae73ec99065eb299b806caVinit Deshpande } 16722451dbcc4f9641df188326215b204b798eb70c46vandwalle 16732451dbcc4f9641df188326215b204b798eb70c46vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 1674c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 16752451dbcc4f9641df188326215b204b798eb70c46vandwalle // enableNetwork with disableOthers=true WifiManager API 16762451dbcc4f9641df188326215b204b798eb70c46vandwalle // As this is a direct user choice, we strongly prefer this configuration, 16772451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence give +/-100 16782451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((lastSelectedConfiguration != null) 16792451dbcc4f9641df188326215b204b798eb70c46vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 16802451dbcc4f9641df188326215b204b798eb70c46vandwalle // candidate is the last selected configuration, 16812451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 16822451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 16832451dbcc4f9641df188326215b204b798eb70c46vandwalle // by reducing order by -100 16842451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - 100; 1685dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 16862f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers -100 " + candidate.configKey() 16872451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + config.configKey() 16882451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 16892451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 16902451dbcc4f9641df188326215b204b798eb70c46vandwalle } 16912451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if ((lastSelectedConfiguration != null) 16922451dbcc4f9641df188326215b204b798eb70c46vandwalle && config.configKey().equals(lastSelectedConfiguration)) { 16932451dbcc4f9641df188326215b204b798eb70c46vandwalle // config is the last selected configuration, 16942451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 16952451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 16962451dbcc4f9641df188326215b204b798eb70c46vandwalle // by increasing order by +100 16972451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + 100; 1698dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (VDBG) { 16992f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers +100 " + config.configKey() 17002451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + candidate.configKey() 17012451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 17022451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 17032451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17042451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17052451dbcc4f9641df188326215b204b798eb70c46vandwalle 1706f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 1707931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Ascending : candidate < config 1708f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1709f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1710f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1711f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1712f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17132451dbcc4f9641df188326215b204b798eb70c46vandwalle // Now, go thru scan result to try finding a better untrusted network 1714833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if (mNetworkScoreCache != null && mAllowUntrustedConnections) { 1715f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 1716f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 1717f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 1718f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 1719f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 1720f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1721f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1722931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Get current date 17232451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 1724c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int currentScore = -10000; 1725c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // The untrusted network with highest score 172625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanDetail untrustedCandidate = null; 17272451dbcc4f9641df188326215b204b798eb70c46vandwalle // Look for untrusted scored network only if the current candidate is bad 1728c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (isBadCandidate(rssi24, rssi5)) { 172925ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail scanDetail : scanResultCache.values()) { 173025ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult result = scanDetail.getScanResult(); 1731c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We look only at untrusted networks with a valid SSID 1732c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // A trusted result would have been looked at thru it's Wificonfiguration 17338639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (TextUtils.isEmpty(result.SSID) || !result.untrusted || 17348639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !isOpenNetwork(result)) { 1735c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle continue; 1736c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 17372c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson String quotedSSID = "\"" + result.SSID + "\""; 17382c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains(quotedSSID)) { 17392ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle // SSID had been Forgotten by user, then don't score it 17402ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle continue; 17412ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle } 1742833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if ((nowMs - result.seen) < mScanResultAutoJoinAge) { 1743c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Increment usage count for the network 17442c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson mWifiConnectionStatistics.incrementOrAddUntrusted(quotedSSID, 0, 1); 1745c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 17462c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson boolean isActiveNetwork = currentConfiguration != null 17472c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson && currentConfiguration.SSID.equals(quotedSSID); 174881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int score = mNetworkScoreCache.getNetworkScore(result, isActiveNetwork); 1749c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (score != WifiNetworkScoreCache.INVALID_NETWORK_SCORE 1750c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle && score > currentScore) { 1751c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Highest score: Select this candidate 1752c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle currentScore = score; 175325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande untrustedCandidate = scanDetail; 1754c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (VDBG) { 1755c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("AutoJoinController: found untrusted candidate " 1756c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + result.SSID 1757dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " RSSI=" + result.level 1758dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " freq=" + result.frequency 1759dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle + " score=" + score); 1760c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1761f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1762f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1763f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1764f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1765c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (untrustedCandidate != null) { 17668639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // At this point, we have an untrusted network candidate. 17678639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // Create the new ephemeral configuration and see if we should switch over 1768833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate = 1769833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.wifiConfigurationFromScanResult(untrustedCandidate); 1770833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.allowedKeyManagement.set(KeyMgmt.NONE); 1771833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.ephemeral = true; 1772fb650bfb264b7ff31c927498faf8343b5895c6abPierre Vandwalle candidate.dirty = true; 1773c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1774c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1775b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 17761ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle long lastUnwanted = 17771ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle System.currentTimeMillis() 17781ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle - mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp; 17791ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (candidate == null 17801ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && lastSelectedConfiguration == null 17811ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && currentConfiguration == null 17821ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && didBailDueToWeakRssi 17831ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && (mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp == 0 1784dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle || lastUnwanted > (1000 * 60 * 60 * 24 * 7)) 17851ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle ) { 17861ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // We are bailing out of autojoin although we are seeing a weak configuration, and 17871ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we didn't find another valid candidate 17881ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we are not connected 17891ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - without a user network selection choice 17901ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - ConnectivityService has not triggered an unwanted network disconnect 17911ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // on this device for a week (hence most likely there is no SIM card or cellular) 17921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // If all those conditions are met, then boost the RSSI of the weak networks 17931ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // that we are seeing so as we will eventually pick one 17941ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount < 10) 17951ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount += 1; 17961ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } else { 17971ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount > 0) 17981ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount -= 1; 17991ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } 18001ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 1801931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1802931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * If candidate is found, check the state of the connection so as 1803931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * to decide if we should be acting on this candidate and switching over 1804931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1805e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle int networkDelta = compareNetwork(candidate, lastSelectedConfiguration); 1806b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (DBG && candidate != null) { 1807b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String doSwitch = ""; 1808b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String current = ""; 1809b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (networkDelta < 0) { 1810b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle doSwitch = " -> not switching"; 1811b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1812b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (currentConfiguration != null) { 18132f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle current = " with current " + currentConfiguration.configKey(); 1814b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1815b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("attemptAutoJoin networkSwitching candidate " 1816b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + candidate.configKey() 1817b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + current 1818c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + " linked=" + (currentConfiguration != null 1819dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle && currentConfiguration.isLinked(candidate)) 1820b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " : delta=" 1821b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + Integer.toString(networkDelta) + " " 1822b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + doSwitch); 1823b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18244dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1825931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1826931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Ask WifiStateMachine permission to switch : 1827931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * if user is currently streaming voice traffic, 1828931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * then we should not be allowed to switch regardless of the delta 1829931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 183077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) { // !!! JNo: Here! 1831b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mStaStaSupported) { 1832b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("mStaStaSupported --> error do nothing now "); 1833b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1834b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) { 1835b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING; 1836b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1837b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING; 1838b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1839b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1840b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto connect with netId " 1841b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(candidate.networkId) 1842b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " to " + candidate.configKey()); 1843b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18442451dbcc4f9641df188326215b204b798eb70c46vandwalle if (didOverride) { 18452451dbcc4f9641df188326215b204b798eb70c46vandwalle candidate.numScorerOverrideAndSwitchedNetwork++; 18462451dbcc4f9641df188326215b204b798eb70c46vandwalle } 1847c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle candidate.numAssociation++; 1848e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoJoinAttempt++; 18499f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 18502c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson if (candidate.ephemeral) { 18512c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson // We found a new candidate that we are going to connect to, then 18522c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson // increase its connection count 18532c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson mWifiConnectionStatistics. 18542c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson incrementOrAddUntrusted(candidate.SSID, 1, 0); 18552c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson } 18562c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson 18572f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (candidate.BSSID == null || candidate.BSSID.equals("any")) { 18582f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // First step we selected the configuration we want to connect to 18592f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Second step: Look for the best Scan result for this configuration 18602f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // TODO this algorithm should really be done in one step 18612f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1862833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1863833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, candidate, mScanResultAutoJoinAge, null); 18642f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && currentBSSID != null 18652f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 18662f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Sanity, we were already asociated to that candidate 18672f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle roamCandidate = null; 18682f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 18692f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && roamCandidate.is5GHz()) { 18702f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // If the configuration hasn't a default BSSID selected, and the best 18712f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // candidate is 5GHZ, then select this candidate so as WifiStateMachine and 18722f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // supplicant will pick it first 18732f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle candidate.autoJoinBSSID = roamCandidate.BSSID; 18742f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) { 18752f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("AutoJoinController: lock to 5GHz " 18762f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + candidate.autoJoinBSSID 18772f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " RSSI=" + roamCandidate.level 18782f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " freq=" + roamCandidate.frequency); 18792f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 1880448c9536a302c58a79e271b1721c08b8882f800evandwalle } else { 1881448c9536a302c58a79e271b1721c08b8882f800evandwalle // We couldnt find a roam candidate 1882448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.autoJoinBSSID = "any"; 18839f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 18849f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1885448c9536a302c58a79e271b1721c08b8882f800evandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 1886dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle candidate.networkId, networkSwitchType, candidate); 188768fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 18884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1889b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1891d4c25fd76644d5490700ae69fada4669de5193a1Pierre Vandwalle if (networkSwitchType == AUTO_JOIN_IDLE && !mWifiConfigStore.enableHalBasedPno.get()) { 1892e67ec726c07410073575473c0f50dc737629f5davandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1893931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Attempt same WifiConfiguration roaming 1894833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1895833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, currentConfiguration, mScanResultAutoJoinAge, currentBSSID); 1896e67ec726c07410073575473c0f50dc737629f5davandwalle if (roamCandidate != null && currentBSSID != null 1897e67ec726c07410073575473c0f50dc737629f5davandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 1898e67ec726c07410073575473c0f50dc737629f5davandwalle roamCandidate = null; 1899e67ec726c07410073575473c0f50dc737629f5davandwalle } 19002f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && mWifiStateMachine.shouldSwitchNetwork(999)) { 1901b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1902b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto roam with netId " 1903b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(currentConfiguration.networkId) 1904b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " " + currentConfiguration.configKey() + " to BSSID=" 1905b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + roamCandidate.BSSID + " freq=" + roamCandidate.frequency 19061ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle + " RSSI=" + roamCandidate.level); 1907b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1908b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_ROAMING; 1909e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoRoamAttempt++; 1910e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 1911b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM, 1912dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle currentConfiguration.networkId, 1, roamCandidate); 191368fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 1914f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1915f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1916b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType)); 191768fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return found; 1918f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 191977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 192077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private void logDenial(String reason, WifiConfiguration config) { 192177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (!DBG) { 192277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return; 192377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 192477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg(reason + config.toString()); 192577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 1926dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle 1927dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle WifiConfiguration getWifiConfiguration(WifiNative.WifiPnoNetwork network) { 1928dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (network.configKey != null) { 1929dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle return mWifiConfigStore.getWifiConfiguration(network.configKey); 1930dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1931dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle return null; 1932dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1933dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle 1934dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle ArrayList<WifiNative.WifiPnoNetwork> getPnoList(WifiConfiguration current) { 1935dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle int size = -1; 19369ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle ArrayList<WifiNative.WifiPnoNetwork> list = new ArrayList<WifiNative.WifiPnoNetwork>(); 1937dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle 1938b0b0cc202b7d7aaad7b3f69d73e9b58ea2968b05Pierre Vandwalle if (mWifiConfigStore.mCachedPnoList != null) { 1939b0b0cc202b7d7aaad7b3f69d73e9b58ea2968b05Pierre Vandwalle size = mWifiConfigStore.mCachedPnoList.size(); 1940dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1941dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle 194221d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 194321d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle String s = ""; 194421d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (current != null) { 194521d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle s = " for: " + current.configKey(); 194621d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 194721d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle Log.e(TAG, " get Pno List total size:" + size + s); 194821d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 1949dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle if (current != null) { 1950dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle String configKey = current.configKey(); 1951dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle /** 1952dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * If we are currently associated to a WifiConfiguration then include 1953dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle * only those networks that have a higher priority 1954dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle */ 1955b0b0cc202b7d7aaad7b3f69d73e9b58ea2968b05Pierre Vandwalle for (WifiNative.WifiPnoNetwork network : mWifiConfigStore.mCachedPnoList) { 1956dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle WifiConfiguration config = getWifiConfiguration(network); 19579ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle if (config == null) { 19589ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle continue; 19599ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle } 19609ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle if (config.autoJoinStatus 19619ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle >= WifiConfiguration.AUTO_JOIN_DISABLED_NO_CREDENTIALS) { 19629ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle continue; 19639ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle } 19649ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle 19659ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle if (!configKey.equals(network.configKey)) { 196621d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle int choice = getConnectChoice(config, current, true); 1967b0b0cc202b7d7aaad7b3f69d73e9b58ea2968b05Pierre Vandwalle if (choice > 0) { 1968b0b0cc202b7d7aaad7b3f69d73e9b58ea2968b05Pierre Vandwalle // config is of higher priority 196921d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle if (DBG) { 197021d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle Log.e(TAG, " Pno List adding:" + network.configKey 197121d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle + " choice " + choice); 197221d43c487ca1f719cd2c170e1fac88c7b62a836aPierre Vandwalle } 1973dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle list.add(network); 1974b0b0cc202b7d7aaad7b3f69d73e9b58ea2968b05Pierre Vandwalle network.rssi_threshold = mWifiConfigStore.thresholdGoodRssi24.get(); 1975dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1976dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1977dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1978dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } else { 19799ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle for (WifiNative.WifiPnoNetwork network : mWifiConfigStore.mCachedPnoList) { 19809ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle WifiConfiguration config = getWifiConfiguration(network); 19819ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle if (config == null) { 19829ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle continue; 19839ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle } 19849ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle if (config.autoJoinStatus 19859ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle >= WifiConfiguration.AUTO_JOIN_DISABLED_NO_CREDENTIALS) { 19869ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle continue; 19879ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle } 19889ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle list.add(network); 19899ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle network.rssi_threshold = mWifiConfigStore.thresholdGoodRssi24.get(); 19909ccffbb6c3fe8eaa7d70cc3076d0dc3c6a9073e7Pierre Vandwalle } 1991dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1992dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle return list; 1993dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle } 1994f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 1995f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1996