WifiAutoJoinController.java revision 4fa99f57077ab287d6ed1b51cf308c44ce8bbe0b
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; 23c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalleimport android.net.wifi.*; 248639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiConfiguration.KeyMgmt; 2516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidsonimport android.os.SystemClock; 2616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidsonimport android.provider.Settings; 27f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalleimport android.os.Process; 28c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalleimport android.text.TextUtils; 29f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log; 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 310c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.ArrayList; 32f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Iterator; 33f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 34f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 35f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 36f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 37f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 39f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 40f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 41f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 42f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 43f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 44f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 45f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 46f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 47f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 48f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 50f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 51f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 53ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean DBG = false; 54ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 56f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 57c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle public static int mScanResultMaximumAge = 40000; /* milliseconds unit */ 58833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle public static int mScanResultAutoJoinAge = 5000; /* milliseconds unit */ 59c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 60453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 62f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private HashMap<String, ScanResult> scanResultCache = 63f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle new HashMap<String, ScanResult>(); 64f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 65c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle private WifiConnectionStatistics mWifiConnectionStatistics; 66c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 678639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** Whether to allow connections to untrusted networks. */ 688639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean mAllowUntrustedConnections = false; 698639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 70c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /* For debug purpose only: if the scored override a score */ 71c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle boolean didOverride = false; 72c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 73931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose the non-auth failure blacklisting after 8 hours 744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListHardMilli = 1000 * 60 * 60 * 8; 75931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose some temporary blacklisting after 30 minutes 764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListSoftMilli = 1000 * 60 * 30; 7727355a942653264388e909a4276196ee63e57811vandwalle 7816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson /** @see android.provider.Settings.Global#WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS */ 7916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private static final long DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS = 1000 * 60; // 1 minute 8016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 81b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_IDLE = 0; 82b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_ROAMING = 1; 83b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_EXTENDED_ROAMING = 2; 84b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3; 85b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 8697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle public static final int HIGH_THRESHOLD_MODIFIER = 5; 8797b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle 881ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // Below are AutoJoin wide parameters indicating if we should be aggressive before joining 891ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // weak network. Note that we cannot join weak network that are going to be marked as unanted by 901ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // ConnectivityService because this will trigger link flapping. 911ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * There was a non-blacklisted configuration that we bailed from because of a weak signal 931ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 941ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle boolean didBailDueToWeakRssi = false; 951ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 961ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * number of time we consecutively bailed out of an eligible network because its signal 971ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * was too weak 981ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 991ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int weakRssiBailCount = 0; 1001ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 101f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 102c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle WifiConnectionStatistics st, WifiNative n) { 103f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 104f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 105f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 106f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 107f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 108c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics = st; 10921bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle scoreManager = 11021bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 111f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 112f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 113f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 115f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 124f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 125ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 126ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (verbose > 0 ) { 127abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = true; 128ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 129ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 130abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = false; 131ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 132ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 133ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 134ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 135931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 136931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Flush out scan results older than mScanResultMaximumAge 137ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * 138931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 139f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 140f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 141931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle delay = mScanResultMaximumAge; // Something sane 142f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 143b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long milli = System.currentTimeMillis(); 144f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 145f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 146f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 147f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 148f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 149f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Iterator<HashMap.Entry<String,ScanResult>> iter = scanResultCache.entrySet().iterator(); 150f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 151f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle HashMap.Entry<String,ScanResult> entry = iter.next(); 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult result = entry.getValue(); 153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.seen + delay) < milli) { 155f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 159f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 160be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int addToScanCache(List<ScanResult> scanList) { 161be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown = 0; // Record number of scan results we knew about 162be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiConfiguration associatedConfig = null; 1637b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle boolean didAssociate = false; 1648242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1660c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 1670c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for(ScanResult result: scanList) { 1691fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (result.SSID == null) continue; 170c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 171c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Make sure we record the last time we saw this result 172f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.seen = System.currentTimeMillis(); 173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 174c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Fetch the previous instance for this result 175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult sr = scanResultCache.get(result.BSSID); 176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (sr != null) { 1778ccabb81ad304b80dc8eaa162fd322643461529bvandwalle if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 1788ccabb81ad304b80dc8eaa162fd322643461529bvandwalle && result.level == 0 1798ccabb81ad304b80dc8eaa162fd322643461529bvandwalle && sr.level < -20) { 1808ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // A 'zero' RSSI reading is most likely a chip problem which returns 1818ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // an unknown RSSI, hence ignore it 1828ccabb81ad304b80dc8eaa162fd322643461529bvandwalle result.level = sr.level; 1838ccabb81ad304b80dc8eaa162fd322643461529bvandwalle } 1848ccabb81ad304b80dc8eaa162fd322643461529bvandwalle 185931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If there was a previous cache result for this BSSID, average the RSSI values 186c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge); 187f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 188c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Remove the previous Scan Result - this is not necessary 189f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.remove(result.BSSID); 1908ccabb81ad304b80dc8eaa162fd322643461529bvandwalle } else if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 && result.level == 0) { 1918ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // A 'zero' RSSI reading is most likely a chip problem which returns 1928ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // an unknown RSSI, hence initialize it to a sane value 1938ccabb81ad304b80dc8eaa162fd322643461529bvandwalle result.level = mWifiConfigStore.scanResultRssiLevelPatchUp; 194e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 195e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 196e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 197e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle WifiKey wkey; 198e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle // Quoted SSIDs are the only one valid at this stage 199e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle try { 200e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 201e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } catch (IllegalArgumentException e) { 202e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID + 203e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle "] ->skipping this network"); 204e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle wkey = null; 205e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 206e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (wkey != null) { 207e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle NetworkKey nkey = new NetworkKey(wkey); 208e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle //if we don't know this scan result then request a score from the scorer 209e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle unknownScanResults.add(nkey); 210e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 211e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 2127b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 2137b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 2147b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 215e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 2167b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is not scored"); 217e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 2180c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 219e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 2207b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 2217b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 2227b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 223e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 224e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 2257b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is scored : " + score); 2260c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 227f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 228f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 229e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // scanResultCache.put(result.BSSID, new ScanResult(result)); 230e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle scanResultCache.put(result.BSSID, result); 231be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // Add this BSSID to the scanResultCache of a Saved WifiConfiguration 2327b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = mWifiConfigStore.updateSavedNetworkHistory(result); 233f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 234be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // If not successful, try to associate this BSSID to an existing Saved WifiConfiguration 2357b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (!didAssociate) { 236be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // We couldn't associate the scan result to a Saved WifiConfiguration 237c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Hence it is untrusted 238c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.untrusted = true; 239f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.associateWithConfiguration(result); 2401fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (associatedConfig != null && associatedConfig.SSID != null) { 241f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 242f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("addToScanCache save associated config " 2438242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + associatedConfig.SSID + " with " + result.SSID 2448242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " status " + associatedConfig.autoJoinStatus 2458242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " reason " + associatedConfig.disableReason 2468242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " tsp " + associatedConfig.blackListTimestamp 2478242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " was " + (now - associatedConfig.blackListTimestamp)); 248f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 249be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle mWifiStateMachine.sendMessage( 250be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiStateMachine.CMD_AUTO_SAVE_NETWORK, associatedConfig); 2517b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = true; 252f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2530d616ef3bf635dff8722e064c0be842676390ed8vandwalle } else { 2540d616ef3bf635dff8722e064c0be842676390ed8vandwalle // If the scan result has been blacklisted fir 18 hours -> unblacklist 2550d616ef3bf635dff8722e064c0be842676390ed8vandwalle if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { 2560d616ef3bf635dff8722e064c0be842676390ed8vandwalle result.setAutoJoinStatus(ScanResult.ENABLED); 2570d616ef3bf635dff8722e064c0be842676390ed8vandwalle } 258f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2597b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (didAssociate) { 260be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown++; 261a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate ++; 262a0708b09ad17b086c008ab100aec7143d7613c80vandwalle } else { 263a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate = 0; 264be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 265f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2660c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 2670c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 2680c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 2690c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 270931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Kick the score manager, we will get updated scores asynchronously 2710c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 2720c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 273be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 274f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 275f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 2770888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle logDbg(message, false); 278ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 279ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 280ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 281ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 2822f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle Log.e(TAG, message + " stack:" 283ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 284ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 285ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 286ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 287ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 2882f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle Log.e(TAG, message); 289ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 290f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 291f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 292931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Called directly from WifiStateMachine 293be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int newSupplicantResults(boolean doAutoJoin) { 294be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown; 295e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle List<ScanResult> scanList = mWifiStateMachine.getScanResultsListNoCopyUnsync(); 296be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown = addToScanCache(scanList); 297f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 298be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle if (DBG) { 299be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) 3002f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " known=" + numScanResultsKnown + " " 3019f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle + doAutoJoin); 302be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 3037806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (doAutoJoin) { 3047806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle attemptAutoJoin(); 3057806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 306005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 307be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 308f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 309f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 310f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 311931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 312931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Not used at the moment 313f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 314f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 315f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 316f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 317f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 318f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 319f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<ScanResult> scanList = null;//mWifiScanner.syncGetScanResultsList(); 320f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 321f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 322f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 323f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 324f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 325005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 326f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 327f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 328931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 329931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * network link quality changed, called directly from WifiTrafficPoller, 330931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * or by listening to Link Quality intent 331931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 332f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 333f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 334f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 335f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 336931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 337f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 338f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 339f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 340f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 341b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * Negatve return values from this functions are meaningless per se, just trying to 342b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * keep them distinct for debug purpose (i.e. -1, -2 etc...) 343931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 344e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle private int compareNetwork(WifiConfiguration candidate, 345e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String lastSelectedConfiguration) { 346b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (candidate == null) 347b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -3; 348b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 349f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 350b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentNetwork == null) { 351c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Return any absurdly high score, if we are not connected there is no current 352c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // network to... 353b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return 1000; 354b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 355f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 356f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 357b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -2; 358f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 359f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 360b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (DBG) { 361e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("compareNetwork will compare " + candidate.configKey() 362e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " with current " + currentNetwork.configKey()); 363b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 364833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 365e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 366e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 367e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 368e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // enableNetwork with disableOthers=true WifiManager API 369e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // As this is a direct user choice, we strongly prefer this configuration, 370e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // hence give +/-100 371e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if ((lastSelectedConfiguration != null) 372e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && currentNetwork.configKey().equals(lastSelectedConfiguration)) { 373e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // currentNetwork is the last selected configuration, 374e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 375e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 376e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by reducing order by -100 377e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order - 100; 378e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 379e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers -100 " + currentNetwork.configKey() 380e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + candidate.configKey() 381e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 382e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 383e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 384e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } else if ((lastSelectedConfiguration != null) 385e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 386e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // candidate 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 increasing order by +100 390e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order + 100; 391e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 392e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers +100 " + candidate.configKey() 393e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + currentNetwork.configKey() 394e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 395e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 396e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 397e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 398e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 399ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle return order; 400f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 401f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 402ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 403ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 404ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 405ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 406ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 407ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 40862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 409ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 410ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 411ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param connect : if the update includes a connect 412931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 41362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 414f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 415f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 416c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + " no selected configuration!"); 417f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 418f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 419f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 420e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 421c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + 422c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle " no SSID in selected configuration!"); 423e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 424e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 425e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 42662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 427931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable autojoin for this network, 42862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 42927355a942653264388e909a4276196ee63e57811vandwalle selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 43062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 431e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle selected.dirty = true; 43262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 433f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 434992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG && userTriggered) { 435f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 436ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 437f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 438992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(selected.connectChoices.size()) 439992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 440f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 441ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 442992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(netId) 443992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 444f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 445f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 447ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 448ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 4492451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice = 0; 450c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int size = 0; 4519f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 4529f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // Reset the triggered disabled count, because user wanted to connect to this 4539f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // configuration, and we were not. 4549f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableLowRSSI = 0; 4559f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableBadRSSI = 0; 4569f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableNotHighRSSI = 0; 4579f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredJoinAttempts++; 4589f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 45962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 46062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 461c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (networks != null) size = networks.size(); 462c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory found " + size + " networks"); 46362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 46462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 465992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG) { 466992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle logDbg("updateConfigurationHistory got " + config.SSID + " nid=" 467992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(config.networkId)); 468992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 469f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 47062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 471ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 47262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 47362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 474f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 4752451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare RSSI values so as to evaluate the strength of the user preference 4762451dbcc4f9641df188326215b204b798eb70c46vandwalle int order = compareWifiConfigurationsRSSI(config, selected, null); 4772451dbcc4f9641df188326215b204b798eb70c46vandwalle 4782451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order < -30) { 4792451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is worse than the visible configuration 4802451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a strong choice so as autojoin cannot override this 4812451dbcc4f9641df188326215b204b798eb70c46vandwalle // for instance, the user has select a network 4822451dbcc4f9641df188326215b204b798eb70c46vandwalle // with 1 bar over a network with 3 bars... 4832451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 60; 4842451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -20) { 4852451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 50; 4862451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -10) { 4872451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 40; 4882f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else if (order < 20) { 4892451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is about same or has a slightly better RSSI 4902451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a weaker choice, here a difference of at least +/-30 in 4912451dbcc4f9641df188326215b204b798eb70c46vandwalle // RSSI comparison triggered by autoJoin will override the choice 4922451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 30; 4932f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else { 4942451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is better than the visible configuration 4952451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence we do not know if the user prefers this configuration strongly 4962451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; 49762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 498f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 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 5112451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer currentChoice = selected.connectChoices.get(config.configKey(true)); 5122f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (currentChoice != null) { 5132f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // User has made this choice multiple time in a row, so bump up a lot 5142f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle choice += currentChoice.intValue(); 5152451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5162f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Add the visible config to the selected's connect choice list 5172f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle selected.connectChoices.put(config.configKey(true), choice); 518f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 51962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 520ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 521ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 52262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 523ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 524931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected from the recently seen config's connectChoice list 52562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 5260888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 5270888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (selected.linkedConfigurations != null) { 528931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected's linked configuration from the 529931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // recently seen config's connectChoice list 5300888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle for (String key : selected.linkedConfigurations.keySet()) { 5310888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle config.connectChoices.remove(key); 5320888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 5330888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 53462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 535ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 536ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 5372451dbcc4f9641df188326215b204b798eb70c46vandwalle // We haven't found the configuration that the user just selected in our 5382451dbcc4f9641df188326215b204b798eb70c46vandwalle // scan cache. 5392451dbcc4f9641df188326215b204b798eb70c46vandwalle // In that case we will need a new scan before attempting to connect to this 5402451dbcc4f9641df188326215b204b798eb70c46vandwalle // configuration anyhow and thus we can process the scan results then. 541ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 542ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + selected.configKey()); 54362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 544f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 54562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 54662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 547ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 54862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 54962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 550f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 551f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 552992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle 553931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // TODO: write only if something changed 554992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (userTriggered || connect) { 555005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 556992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 557f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 558f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5592451dbcc4f9641df188326215b204b798eb70c46vandwalle int getConnectChoice(WifiConfiguration source, WifiConfiguration target) { 5602451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer choice = null; 5612451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source == null || target == null) { 5622451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 563f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 564f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5652451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source.connectChoices != null 5662451dbcc4f9641df188326215b204b798eb70c46vandwalle && source.connectChoices.containsKey(target.configKey(true))) { 5672451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = source.connectChoices.get(target.configKey(true)); 5682451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (source.linkedConfigurations != null) { 569f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 570f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 571f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 572f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 5732451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = config.connectChoices.get(target.configKey(true)); 574f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 575f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 576f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 5772451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5782451dbcc4f9641df188326215b204b798eb70c46vandwalle 5792451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice == null) { 5802451dbcc4f9641df188326215b204b798eb70c46vandwalle //We didn't find the connect choice 5812451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 5822451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 5832451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice.intValue() < 0) { 5842451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; // Compatibility with older files 5852451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5862451dbcc4f9641df188326215b204b798eb70c46vandwalle return choice.intValue(); 5872451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5882451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5892451dbcc4f9641df188326215b204b798eb70c46vandwalle 590815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int compareWifiConfigurationsFromVisibility(WifiConfiguration a, int aRssiBoost, 591815788ba7838fc54310baed3deb9b95548e0ce69vandwalle WifiConfiguration b, int bRssiBoost) { 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 */ 609815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.visibility.rssi5, a.configKey() + "->"); 610815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.visibility.rssi5, b.configKey() + "->"); 6112451dbcc4f9641df188326215b204b798eb70c46vandwalle 612815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for a 613f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility.rssi5 + aRssiBoost5 > a.visibility.rssi24) { 6142451dbcc4f9641df188326215b204b798eb70c46vandwalle // Prefer a's 5GHz 615815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aPrefers5GHz = true; 616815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 617815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 618815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for b 619815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (b.visibility.rssi5 + bRssiBoost5 > b.visibility.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 629815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aScore = a.visibility.rssi5 + aRssiBoost; 630815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 631815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only a is on 5GHz, then apply the 5GHz preference boost to a 632815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aScore = a.visibility.rssi5 + aRssiBoost + aRssiBoost5; 633815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 6342451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 635815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aScore = a.visibility.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 643815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bScore = b.visibility.rssi5 + bRssiBoost; 644815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 645815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only b is on 5GHz, then apply the 5GHz preference boost to b 646815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bScore = b.visibility.rssi5 + bRssiBoost + bRssiBoost5; 647815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 648815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 649815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bScore = b.visibility.rssi24 + bRssiBoost; 650815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 651815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (VDBG) { 652815788ba7838fc54310baed3deb9b95548e0ce69vandwalle logDbg(" " + a.configKey() + " is5=" + aPrefers5GHz + " score=" + aScore 653f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " " + b.configKey() + " is5=" + bPrefers5GHz + " score=" + bScore); 654815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 655f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 656f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle // Debug only, record RSSI comparison parameters 657f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility != null) { 658f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.score = aScore; 659f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.currentNetworkBoost = aRssiBoost; 660f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.bandPreferenceBoost = aRssiBoost5; 661f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 662f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (b.visibility != null) { 663f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.score = bScore; 664f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.currentNetworkBoost = bRssiBoost; 665f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.bandPreferenceBoost = bRssiBoost5; 666f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 667f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 668815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Compare a and b 669815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If a score is higher then a > b and the order is descending (negative) 670815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If b score is higher then a < b and the order is ascending (positive) 671815788ba7838fc54310baed3deb9b95548e0ce69vandwalle return bScore - aScore; 672f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 673f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6742451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50] 6752451dbcc4f9641df188326215b204b798eb70c46vandwalle // The result represents "approximately" an RSSI difference measured in dBM 6762451dbcc4f9641df188326215b204b798eb70c46vandwalle // Adjusted with various parameters: 6772451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) current network gets a +15 boost 6782451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) 5GHz signal, if they are strong enough, get a +15 or +25 boost, representing the 6792451dbcc4f9641df188326215b204b798eb70c46vandwalle // fact that at short range we prefer 5GHz band as it is cleaner of interference and 6802451dbcc4f9641df188326215b204b798eb70c46vandwalle // provides for wider channels 6812451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b, 6822451dbcc4f9641df188326215b204b798eb70c46vandwalle String currentConfiguration) { 683f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 6842451dbcc4f9641df188326215b204b798eb70c46vandwalle 6852451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost used so as to favor current config 6862451dbcc4f9641df188326215b204b798eb70c46vandwalle int aRssiBoost = 0; 6872451dbcc4f9641df188326215b204b798eb70c46vandwalle int bRssiBoost = 0; 6882451dbcc4f9641df188326215b204b798eb70c46vandwalle 6892451dbcc4f9641df188326215b204b798eb70c46vandwalle int scoreA; 6902451dbcc4f9641df188326215b204b798eb70c46vandwalle int scoreB; 6912451dbcc4f9641df188326215b204b798eb70c46vandwalle 6922451dbcc4f9641df188326215b204b798eb70c46vandwalle // Retrieve the visibility 693f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 694f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 695f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 6962451dbcc4f9641df188326215b204b798eb70c46vandwalle // Error visibility wasn't set 697b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations NULL band status!"); 698f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 699f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7002451dbcc4f9641df188326215b204b798eb70c46vandwalle 7012451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis, boost RSSI of current configuration 7022451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != currentConfiguration) { 7032451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(currentConfiguration)) { 70493a1fddee50a244d31036cddae6b7db6630fd93dvandwalle aRssiBoost = mWifiConfigStore.currentNetworkBoost; 7052451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(currentConfiguration)) { 70693a1fddee50a244d31036cddae6b7db6630fd93dvandwalle bRssiBoost = mWifiConfigStore.currentNetworkBoost; 7072451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7082451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7092451dbcc4f9641df188326215b204b798eb70c46vandwalle 7102451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 711b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI: " + a.configKey() 712f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " rssi=" + Integer.toString(astatus.rssi24) 713c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + "," + Integer.toString(astatus.rssi5) 7142451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(aRssiBoost) 715f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " " + b.configKey() + " rssi=" 716c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi24) + "," 717c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi5) 7182451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(bRssiBoost) 7192451dbcc4f9641df188326215b204b798eb70c46vandwalle ); 720f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7212451dbcc4f9641df188326215b204b798eb70c46vandwalle 722815788ba7838fc54310baed3deb9b95548e0ce69vandwalle order = compareWifiConfigurationsFromVisibility(a, aRssiBoost, b, bRssiBoost); 7232451dbcc4f9641df188326215b204b798eb70c46vandwalle 7242451dbcc4f9641df188326215b204b798eb70c46vandwalle // Normalize the order to [-50, +50] 7252451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 50) order = 50; 7262451dbcc4f9641df188326215b204b798eb70c46vandwalle else if (order < -50) order = -50; 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 753833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * 7542451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsWithScorer(WifiConfiguration a, WifiConfiguration b) { 7552451dbcc4f9641df188326215b204b798eb70c46vandwalle 75681c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean aIsActive = false; 75781c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean bIsActive = false; 7582451dbcc4f9641df188326215b204b798eb70c46vandwalle 7592451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis : boost RSSI of current configuration before 7602451dbcc4f9641df188326215b204b798eb70c46vandwalle // looking up the score 7612451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != mCurrentConfigurationKey) { 7622451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(mCurrentConfigurationKey)) { 76381c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson aIsActive = true; 7642451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(mCurrentConfigurationKey)) { 76581c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson bIsActive = true; 7662451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7672451dbcc4f9641df188326215b204b798eb70c46vandwalle } 768833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreA = getConfigNetworkScore(a, mScanResultAutoJoinAge, aIsActive); 769833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreB = getConfigNetworkScore(b, mScanResultAutoJoinAge, bIsActive); 7702451dbcc4f9641df188326215b204b798eb70c46vandwalle 7712451dbcc4f9641df188326215b204b798eb70c46vandwalle // Both configurations need to have a score for the scorer to be used 7722451dbcc4f9641df188326215b204b798eb70c46vandwalle // ...and the scores need to be different:-) 7732451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA == WifiNetworkScoreCache.INVALID_NETWORK_SCORE 7742451dbcc4f9641df188326215b204b798eb70c46vandwalle || scoreB == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 775e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 776b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer no-scores: " 777e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + a.configKey() 778e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " " 779e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + b.configKey()); 780e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 7812451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 7822451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7832451dbcc4f9641df188326215b204b798eb70c46vandwalle 7842451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 7852451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 7862451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA < scoreB) { 7872451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; 7882451dbcc4f9641df188326215b204b798eb70c46vandwalle } if (scoreA > scoreB) { 7892451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; 7902451dbcc4f9641df188326215b204b798eb70c46vandwalle } 791b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer " + a.configKey() 7922451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 7932451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 7942451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 7952451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 796e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreA 7972451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 7982451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 7992451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 8002451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 8012451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 802e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreB 8032451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + Integer.toString(scoreB - scoreA)); 8042451dbcc4f9641df188326215b204b798eb70c46vandwalle } 805c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 8062451dbcc4f9641df188326215b204b798eb70c46vandwalle // If scoreA > scoreB, the comparison is descending hence the return value is negative 8072451dbcc4f9641df188326215b204b798eb70c46vandwalle return scoreB - scoreA; 8082451dbcc4f9641df188326215b204b798eb70c46vandwalle } 809833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 8102451dbcc4f9641df188326215b204b798eb70c46vandwalle 811f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 812f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 813f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 814f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 815453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 816453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 817453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 8182451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((a.linkedConfigurations.get(b.configKey(true)) != null) 8192451dbcc4f9641df188326215b204b798eb70c46vandwalle && (b.linkedConfigurations.get(a.configKey(true)) != null)) { 820f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 821f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 822f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 823f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 824f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 825f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 826b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + b.configKey() 827453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 828f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 829931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return 1; // b is of higher priority - ascending 830f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 831f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 832f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 833b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + a.configKey() 834453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 835f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 836931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return -1; // a is of higher priority - descending 837f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 838f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8392451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply RSSI, in the range [-5, +5] 8402451dbcc4f9641df188326215b204b798eb70c46vandwalle // after band adjustment, +n difference roughly corresponds to +10xn dBm 8412451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + compareWifiConfigurationsRSSI(a, b, mCurrentConfigurationKey); 842f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8432451dbcc4f9641df188326215b204b798eb70c46vandwalle // If the configurations are not linked, compare by user's choice, only a 8442451dbcc4f9641df188326215b204b798eb70c46vandwalle // very high RSSI difference can then override the choice 8452451dbcc4f9641df188326215b204b798eb70c46vandwalle if (!linked) { 8462451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice; 847f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8482451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(a, b); 8492451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 850931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 8512451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - choice; 852f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 853b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + a.configKey() 854453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 855b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " due to user choice of " + choice 856b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order -> " + Integer.toString(order)); 857f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 858f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility != null) { 859f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceBoost = choice; 860f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceConfig = b.configKey(); 861f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 8622451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8632451dbcc4f9641df188326215b204b798eb70c46vandwalle 8642451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(b, a); 8652451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 866931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 8672451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + choice; 8684dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 869b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + b.configKey() + " over " 870b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + a.configKey() + " due to user choice of " + choice 871b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order ->" + Integer.toString(order)); 872f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 873f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (b.visibility != null) { 874f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceBoost = choice; 875f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceConfig = a.configKey(); 876f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 877f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 878f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 879ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 880f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 881931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // We don't know anything - pick the last seen i.e. K behavior 882931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // we should do this only for recently picked configurations 883f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 884931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 8852451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 886b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers -1 " + a.configKey() + " over " 887453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 888f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 889f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 890f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 891f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 892931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 8932451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 894b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers +1 " + b.configKey() + " over " 895453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 896f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 8972451dbcc4f9641df188326215b204b798eb70c46vandwalle order = 1; 898f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 899f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 900f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 901f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 902931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if (order > 0) { 903f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 904931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } else if (order < 0) { 905f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 906931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } 907f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9082451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 909b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("compareWifiConfigurations: " + a.configKey() + sorder 910453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 911f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 912f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 913f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 914f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 915f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 916c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle boolean isBadCandidate(int rssi5, int rssi24) { 917c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle return (rssi5 < -80 && rssi24 < -90); 918c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 919c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 920833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /* 921c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int compareWifiConfigurationsTop(WifiConfiguration a, WifiConfiguration b) { 922c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int scorerOrder = compareWifiConfigurationsWithScorer(a, b); 923c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int order = compareWifiConfigurations(a, b); 924c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 925c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder * order < 0) { 926b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (VDBG) { 927b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" -> compareWifiConfigurationsTop: " + 928b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle "scorer override " + scorerOrder + " " + order); 929b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 930c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // For debugging purpose, remember that an override happened 931c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // during that autojoin Attempt 932c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = true; 933c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle a.numScorerOverride++; 934c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle b.numScorerOverride++; 935c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 936c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 937c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder != 0) { 938c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If the scorer came up with a result then use the scorer's result, else use 939c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // the order provided by the base comparison function 940c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle order = scorerOrder; 941c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 942c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle return order; 943c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 944833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 945c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 9469f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle public int rssiBoostFrom5GHzRssi(int rssi, String dbg) { 9470eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!mWifiConfigStore.enable5GHzPreference) { 9480eebae7334d6129f7ca1344e4b20199794994358vandwalle return 0; 9490eebae7334d6129f7ca1344e4b20199794994358vandwalle } 950e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 9510eebae7334d6129f7ca1344e4b20199794994358vandwalle > mWifiConfigStore.bandPreferenceBoostThreshold5) { 952e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 2 dB for each point 953e67ec726c07410073575473c0f50dc737629f5davandwalle // Start boosting at -65 954e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 20 if above -55 955e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 40 if abore -45 9560eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferenceBoostFactor5 9570eebae7334d6129f7ca1344e4b20199794994358vandwalle *(rssi - mWifiConfigStore.bandPreferenceBoostThreshold5); 958e67ec726c07410073575473c0f50dc737629f5davandwalle if (boost > 50) { 959815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // 50 dB boost allows jumping from 2.4 to 5GHz 960e67ec726c07410073575473c0f50dc737629f5davandwalle // consistently 961e67ec726c07410073575473c0f50dc737629f5davandwalle boost = 50; 962e67ec726c07410073575473c0f50dc737629f5davandwalle } 9639f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle if (VDBG && dbg != null) { 964f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle logDbg(" " + dbg + ": rssi5 " + rssi + " 5GHz-boost " + boost); 9659f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 966e67ec726c07410073575473c0f50dc737629f5davandwalle return boost; 967e67ec726c07410073575473c0f50dc737629f5davandwalle } 968e67ec726c07410073575473c0f50dc737629f5davandwalle 969e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 9700eebae7334d6129f7ca1344e4b20199794994358vandwalle < mWifiConfigStore.bandPreferencePenaltyThreshold5) { 9710eebae7334d6129f7ca1344e4b20199794994358vandwalle // penalize if < -75 9720eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferencePenaltyFactor5 9730eebae7334d6129f7ca1344e4b20199794994358vandwalle *(rssi - mWifiConfigStore.bandPreferencePenaltyThreshold5); 9740eebae7334d6129f7ca1344e4b20199794994358vandwalle return boost; 975e67ec726c07410073575473c0f50dc737629f5davandwalle } 976e67ec726c07410073575473c0f50dc737629f5davandwalle return 0; 977e67ec726c07410073575473c0f50dc737629f5davandwalle } 978c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /** 979e67ec726c07410073575473c0f50dc737629f5davandwalle * attemptRoam() function implements the core of the same SSID switching algorithm 980e67ec726c07410073575473c0f50dc737629f5davandwalle * 981e67ec726c07410073575473c0f50dc737629f5davandwalle * Run thru all recent scan result of a WifiConfiguration and select the 982e67ec726c07410073575473c0f50dc737629f5davandwalle * best one. 983c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle */ 984e67ec726c07410073575473c0f50dc737629f5davandwalle public ScanResult attemptRoam(ScanResult a, 985e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration current, int age, String currentBSSID) { 986b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current == null) { 987b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 988b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam not associated"); 989b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 990e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 9914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 992b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current.scanResultCache == null) { 993b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 994b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam no scan cache"); 995b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 996e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 9974dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 998b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle if (current.scanResultCache.size() > 6) { 999b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1000c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam scan cache size " 1001c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + current.scanResultCache.size() + " --> bail"); 1002b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1003931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Implement same SSID roaming only for configurations 1004c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // that have less than 4 BSSIDs 1005e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10064dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1007b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 10082f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (current.BSSID != null && !current.BSSID.equals("any")) { 1009b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 10102f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("attemptRoam() BSSID is set " 10112f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + current.BSSID + " -> bail"); 1012b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1013e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10144dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10154dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1016931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Determine which BSSID we want to associate to, taking account 1017c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // relative strength of 5 and 2.4 GHz BSSIDs 10182451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 10194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 102097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle for (ScanResult b : current.scanResultCache.values()) { 102197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost5 = 0; 102297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost5 = 0; 102397b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost = 0; 102497b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost = 0; 1025931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if ((b.seen == 0) || (b.BSSID == null) 10260d616ef3bf635dff8722e064c0be842676390ed8vandwalle || ((nowMs - b.seen) > age) 1027e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.autoJoinStatus != ScanResult.ENABLED 1028e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.numIpConfigFailures > 8) { 10294dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 10303a2a3d226881cce8a4e511302231d843b0def303vandwalle } 10314dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1032931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Pick first one 10334dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (a == null) { 10344dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle a = b; 10354dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 10364dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10374dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1038e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (b.numIpConfigFailures < (a.numIpConfigFailures - 1)) { 1039e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // Prefer a BSSID that doesn't have less number of Ip config failures 1040e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptRoam: " 1041e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + b.BSSID + " rssi=" + b.level + " ipfail=" +b.numIpConfigFailures 1042e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + b.frequency 1043e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " > " 1044e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + a.BSSID + " rssi=" + a.level + " ipfail=" +a.numIpConfigFailures 1045e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + a.frequency); 1046e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle a = b; 1047e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle continue; 1048e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1049e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 10502451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply hysteresis: we favor the currentBSSID by giving it a boost 10517806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(b.BSSID)) { 1052931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 10530eebae7334d6129f7ca1344e4b20199794994358vandwalle if (b.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5) { 10540eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1055c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 10560eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1057c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 10584dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10597806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(a.BSSID)) { 10600eebae7334d6129f7ca1344e4b20199794994358vandwalle if (a.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5) { 1061931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 10620eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1063c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 10640eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1065c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 10664dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10672451dbcc4f9641df188326215b204b798eb70c46vandwalle 106897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve 10692451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost the BSSID if it is on 5GHz, above a threshold 10702451dbcc4f9641df188326215b204b798eb70c46vandwalle // But penalize it if it is on 5GHz and below threshold 107197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // 107297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // With he current threshold values, 5GHz network with RSSI above -55 107397b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Are given a boost of 30DB which is enough to overcome the current BSSID 107497b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases 10759f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // 10769f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // The "current BSSID" Boost must be added to the BSSID's level so as to introduce\ 10779f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // soem amount of hysteresis 1078e67ec726c07410073575473c0f50dc737629f5davandwalle if (b.is5GHz()) { 10799f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.level + bRssiBoost, b.BSSID); 10804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1081e67ec726c07410073575473c0f50dc737629f5davandwalle if (a.is5GHz()) { 10829f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.level + aRssiBoost, a.BSSID); 10834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 10854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 1086c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle String comp = " < "; 1087c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1088c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle comp = " > "; 1089c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 10904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptRoam: " 1091c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost) 109297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency 109397b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + comp 1094c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost) 1095c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency); 1096c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 1097c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle 10982451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare the RSSIs after applying the hysteresis boost and the 5GHz 10992451dbcc4f9641df188326215b204b798eb70c46vandwalle // boost if applicable 1100c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1101931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // b is the better BSSID 1102c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle a = b; 11034dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11044dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11053a2a3d226881cce8a4e511302231d843b0def303vandwalle if (a != null) { 11063a2a3d226881cce8a4e511302231d843b0def303vandwalle if (VDBG) { 11077806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle StringBuilder sb = new StringBuilder(); 1108e67ec726c07410073575473c0f50dc737629f5davandwalle sb.append("attemptRoam: " + current.configKey() + 1109e67ec726c07410073575473c0f50dc737629f5davandwalle " Found " + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency); 11107806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null) { 11117806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append(" Current: " + currentBSSID); 11127806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 11137806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append("\n"); 11147806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle logDbg(sb.toString()); 11153a2a3d226881cce8a4e511302231d843b0def303vandwalle } 11164dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11173a2a3d226881cce8a4e511302231d843b0def303vandwalle return a; 11184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1120931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 11212451dbcc4f9641df188326215b204b798eb70c46vandwalle * getNetworkScore() 11222451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11232451dbcc4f9641df188326215b204b798eb70c46vandwalle * if scorer is present, get the network score of a WifiConfiguration 11242451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11252451dbcc4f9641df188326215b204b798eb70c46vandwalle * Note: this should be merge with setVisibility 11262451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11272451dbcc4f9641df188326215b204b798eb70c46vandwalle * @param config 11282451dbcc4f9641df188326215b204b798eb70c46vandwalle * @return score 11292451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 113081c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int getConfigNetworkScore(WifiConfiguration config, int age, boolean isActive) { 11312451dbcc4f9641df188326215b204b798eb70c46vandwalle 11322451dbcc4f9641df188326215b204b798eb70c46vandwalle if (mNetworkScoreCache == null) { 1133e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1134b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1135e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scorer, hence no scores"); 1136e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 11371db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11381db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 11391db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (config.scanResultCache == null) { 1140e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1141b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1142e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scan cache"); 1143e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 11441db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11452451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11462451dbcc4f9641df188326215b204b798eb70c46vandwalle 11472451dbcc4f9641df188326215b204b798eb70c46vandwalle // Get current date 11482451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 11492451dbcc4f9641df188326215b204b798eb70c46vandwalle 11501db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle int startScore = -10000; 11511db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle 11522451dbcc4f9641df188326215b204b798eb70c46vandwalle // Run thru all cached scan results 11531db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle for (ScanResult result : config.scanResultCache.values()) { 11542451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((nowMs - result.seen) < age) { 115581c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int sc = mNetworkScoreCache.getNetworkScore(result, isActive); 11561db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (sc > startScore) { 11571db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = sc; 11582451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11592451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11602451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11611db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (startScore == -10000) { 11621db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11631db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 1164e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1165e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (startScore == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 1166b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1167e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no available score"); 1168e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } else { 1169b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 117081c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson + " isActive=" + isActive 1171e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " score = " + Integer.toString(startScore)); 1172e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1173e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1174e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle 11751db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return startScore; 11762451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11772451dbcc4f9641df188326215b204b798eb70c46vandwalle 11782451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 11798639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson * Set whether connections to untrusted connections are allowed. 11808639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson */ 11818639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson void setAllowUntrustedConnections(boolean allow) { 11828639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson boolean changed = mAllowUntrustedConnections != allow; 11838639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson mAllowUntrustedConnections = allow; 11848639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (changed) { 1185005c1ef113192f898499a407dd266393a8d6b076vandwalle // Trigger a scan so as to reattempt autojoin 1186005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiStateMachine.startScanForUntrustedSettingChange(); 11878639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 11888639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 11898639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 11908639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean isOpenNetwork(ScanResult result) { 11918639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson return !result.capabilities.contains("WEP") && 11928639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("PSK") && 11938639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("EAP"); 11948639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 11958639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 119616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private boolean haveRecentlySeenScoredBssid(WifiConfiguration config) { 119716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long ephemeralOutOfRangeTimeoutMs = Settings.Global.getLong( 119816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson mContext.getContentResolver(), 119916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson Settings.Global.WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS, 120016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS); 120116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 120216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Check whether the currently selected network has a score curve. If 120316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // ephemeralOutOfRangeTimeoutMs is <= 0, then this is all we check, and we stop here. 120416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Otherwise, we stop here if the currently selected network has a score. If it doesn't, we 120516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // keep going - it could be that another BSSID is in range (has been seen recently) which 120616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // has a score, even if the one we're immediately connected to doesn't. 120716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson ScanResult currentScanResult = mWifiStateMachine.getCurrentScanResult(); 120816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson boolean currentNetworkHasScoreCurve = mNetworkScoreCache.hasScoreCurve(currentScanResult); 120916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (ephemeralOutOfRangeTimeoutMs <= 0 || currentNetworkHasScoreCurve) { 121016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 121116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (currentNetworkHasScoreCurve) { 121216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has a score curve, keeping network: " 121316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson + currentScanResult); 121416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } else { 121516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has no score curve, giving up: " + config.SSID); 121616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 121716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 121816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return currentNetworkHasScoreCurve; 121916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 122016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 122116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (config.scanResultCache == null || config.scanResultCache.isEmpty()) { 122216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 122316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 122416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 122516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long currentTimeMs = System.currentTimeMillis(); 122616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson for (ScanResult result : config.scanResultCache.values()) { 122716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (currentTimeMs > result.seen 122816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson && currentTimeMs - result.seen < ephemeralOutOfRangeTimeoutMs 122916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson && mNetworkScoreCache.hasScoreCurve(result)) { 123016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 123116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Found scored BSSID, keeping network: " + result.BSSID); 123216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 123316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return true; 123416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 123516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 123616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 123716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 123816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("No recently scored BSSID found, giving up connection: " + config.SSID); 123916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 124016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 124116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 124216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 12438639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** 1244931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * attemptAutoJoin() function implements the core of the a network switching algorithm 124568fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle * Return false if no acceptable networks were found. 1246931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 124768fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean attemptAutoJoin() { 124868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean found = false; 1249c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = false; 12501ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = false; 1251b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkSwitchType = AUTO_JOIN_IDLE; 12524dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 12538242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 12548242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle 12558c9088d11880553458f09377cc60d6eb7e66747bvandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 12568c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1257931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reset the currentConfiguration Key, and set it only if WifiStateMachine and 1258453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 1259453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 1260453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 1261453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1262f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 1263f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1264931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Obtain the subset of recently seen networks 1265833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle List<WifiConfiguration> list = 1266833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.getRecentConfiguredNetworks(mScanResultAutoJoinAge, false); 1267f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 12682f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) logDbg("attemptAutoJoin nothing known=" + 12692f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle mWifiConfigStore.getconfiguredNetworkSize()); 127068fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1271f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1272f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1273931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Find the currently connected network: ask the supplicant directly 127499d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle String val = mWifiNative.status(true); 1275f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String status[] = val.split("\\r?\\n"); 1276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1277f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("attemptAutoJoin() status=" + val + " split=" 1278f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(status.length)); 1279f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1280f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1281b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int supplicantNetId = -1; 1282f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : status) { 1283f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (key.regionMatches(0, "id=", 0, 3)) { 1284f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int idx = 3; 1285b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId = 0; 1286f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (idx < key.length()) { 1287f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle char c = key.charAt(idx); 1288f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1289f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((c >= 0x30) && (c <= 0x39)) { 1290b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId *= 10; 1291b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId += c - 0x30; 1292f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle idx++; 1293f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1294f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 1295f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1296f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 129756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle } else if (key.contains("wpa_state=ASSOCIATING") 129856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle || key.contains("wpa_state=ASSOCIATED") 129956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle || key.contains("wpa_state=FOUR_WAY_HANDSHAKE") 130056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle || key.contains("wpa_state=GROUP_KEY_HANDSHAKE")) { 130156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle if (DBG) { 130256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle logDbg("attemptAutoJoin: bail out due to sup state " + key); 130356d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle } 130456d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // After WifiStateMachine ask the supplicant to associate or reconnect 130556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // we might still obtain scan results from supplicant 130656d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // however the supplicant state in the mWifiInfo and supplicant state tracker 130756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // are updated when we get the supplicant state change message which can be 130856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // processed after the SCAN_RESULT message, so at this point the framework doesn't 130956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // know that supplicant is ASSOCIATING. 131056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // A good fix for this race condition would be for the WifiStateMachine to add 131156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // a new transient state where it expects to get the supplicant message indicating 131256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // that it started the association process and within which critical operations 131356d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // like autojoin should be deleted. 131456d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle 131556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // This transient state would remove the need for the roam Wathchdog which 131656d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // basically does that. 131756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle 131856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // At the moment, we just query the supplicant state synchronously with the 131956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // mWifiNative.status() command, which allow us to know that 132056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // supplicant has started association process, even though we didnt yet get the 132156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // SUPPLICANT_STATE_CHANGE message. 132268fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1323f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1324f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1325ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 13267806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle String conf = ""; 1327b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String last = ""; 13287806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentConfiguration != null) { 1329e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle conf = " current=" + currentConfiguration.configKey(); 1330b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1331b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (lastSelectedConfiguration != null) { 13322f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle last = " last=" + lastSelectedConfiguration; 13337806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 1334ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 1335b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + conf + last 1336b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " ---> suppNetId=" + Integer.toString(supplicantNetId)); 1337ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1338f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1339453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (currentConfiguration != null) { 13402451dbcc4f9641df188326215b204b798eb70c46vandwalle if (supplicantNetId != currentConfiguration.networkId 1341005c1ef113192f898499a407dd266393a8d6b076vandwalle // https://b.corp.google.com/issue?id=16484607 1342005c1ef113192f898499a407dd266393a8d6b076vandwalle // mark this condition as an error only if the mismatched networkId are valid 13432451dbcc4f9641df188326215b204b798eb70c46vandwalle && supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID 13442451dbcc4f9641df188326215b204b798eb70c46vandwalle && currentConfiguration.networkId != WifiConfiguration.INVALID_NETWORK_ID) { 1345453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 1346b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + Integer.toString(supplicantNetId) + " WifiStateMachine=" 1347453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + Integer.toString(currentConfiguration.networkId)); 1348b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle mWifiStateMachine.disconnectCommand(); 134968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 13508639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } else if (currentConfiguration.ephemeral && (!mAllowUntrustedConnections || 135116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson !haveRecentlySeenScoredBssid(currentConfiguration))) { 13528639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // The current connection is untrusted (the framework added it), but we're either 135316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // no longer allowed to connect to such networks, the score has been nullified 135416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // since we connected, or the scored BSSID has gone out of range. 135516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Drop the current connection and perform the rest of autojoin. 13568639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network"); 1357f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle mWifiStateMachine.disconnectCommand(Process.WIFI_UID, 1358f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle mAllowUntrustedConnections ? 1 : 0); 135968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1360453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else { 1361453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = currentConfiguration.configKey(); 1362453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 13638c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle } else { 13648c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle if (supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID) { 13658c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle // Maybe in the process of associating, skip this attempt 136668fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 13678c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle } 1368453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 1369453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1370b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int currentNetId = -1; 1371b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentConfiguration != null) { 1372931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If we are associated to a configuration, it will 1373b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // be compared thru the compareNetwork function 1374b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle currentNetId = currentConfiguration.networkId; 1375b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 1376b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle 1377931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1378931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Run thru all visible configurations without looking at the one we 1379c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle * are currently associated to 13804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * select Best Network candidate from known WifiConfigurations 1381931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1382f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 1383e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 1384b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle continue; 1385e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 1386e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 138727355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 138827355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) { 1389abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Wait for 5 minutes before reenabling config that have known, 1390abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // repeated connection or DHCP failures 1391abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE 1392abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle || config.disableReason 1393abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle == WifiConfiguration.DISABLED_ASSOCIATION_REJECT 1394abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle || config.disableReason 1395abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle == WifiConfiguration.DISABLED_AUTH_FAILURE) { 1396abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if (config.blackListTimestamp == 0 1397abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle || (config.blackListTimestamp > now)) { 1398abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Sanitize the timestamp 1399abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.blackListTimestamp = now; 1400abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1401abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if ((now - config.blackListTimestamp) > 1402abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle mWifiConfigStore.wifiConfigBlacklistMinTimeMilli) { 1403abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Re-enable the WifiConfiguration 1404abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.status = WifiConfiguration.Status.ENABLED; 1405abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle 1406abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Reset the blacklist condition 1407abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.numConnectionFailures = 0; 1408abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.numIpConfigFailures = 0; 1409abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.numAuthFailures = 0; 1410abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 1411abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle 1412abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.dirty = true; 1413abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } else { 1414abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if (VDBG) { 1415abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle long delay = mWifiConfigStore.wifiConfigBlacklistMinTimeMilli 1416abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle - (now - config.blackListTimestamp); 1417abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle logDbg("attemptautoJoin " + config.configKey() 1418abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle + " dont unblacklist yet, waiting for " 1419abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle + delay + " ms"); 1420abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1421abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1422abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1423931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Avoid networks disabled because of AUTH failure altogether 1424ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1425ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin skip candidate due to auto join status " 1426ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + Integer.toString(config.autoJoinStatus) + " key " 1427e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + config.configKey(true) 14288242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " reason " + config.disableReason); 1429ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1430f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1431f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1432f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1433931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to un-blacklist based on elapsed time 143427355a942653264388e909a4276196ee63e57811vandwalle if (config.blackListTimestamp > 0) { 143527355a942653264388e909a4276196ee63e57811vandwalle if (now < config.blackListTimestamp) { 1436931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1437931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * looks like there was a change in the system clock since we black listed, and 1438931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * timestamp is not meaningful anymore, hence lose it. 1439931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * this event should be rare enough so that we still want to lose the black list 14402451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 144127355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 144227355a942653264388e909a4276196ee63e57811vandwalle } else { 14434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now - config.blackListTimestamp) > loseBlackListHardMilli) { 1444931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable it after 18 hours, i.e. next day 144527355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 14464dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) { 1447931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose blacklisting due to bad link 144827355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 8); 144927355a942653264388e909a4276196ee63e57811vandwalle } 145027355a942653264388e909a4276196ee63e57811vandwalle } 145127355a942653264388e909a4276196ee63e57811vandwalle } 145227355a942653264388e909a4276196ee63e57811vandwalle 1453931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to unblacklist based on good visibility 14548c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle if (config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Soft 14558c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle && config.visibility.rssi24 14568c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle < mWifiConfigStore.thresholdUnblacklistThreshold24Soft) { 145727355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 1458c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("attemptAutoJoin do not unblacklist due to low visibility " 14594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 14604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) 14614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + config.visibility.rssi24 14624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.rssi5 14634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 14644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 146527355a942653264388e909a4276196ee63e57811vandwalle } 14668c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle } else if (config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Hard 14678c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle && config.visibility.rssi24 14688c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle < mWifiConfigStore.thresholdUnblacklistThreshold24Hard) { 1469931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If the network is simply temporary disabled, don't allow reconnect until 1470931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // RSSI becomes good enough 147127355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 1); 147227355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 147327355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin good candidate seen, bumped soft -> status=" 147427355a942653264388e909a4276196ee63e57811vandwalle + config.autoJoinStatus 1475b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " " + config.configKey(true) + " rssi=(" 14764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 14774dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 14784dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 147927355a942653264388e909a4276196ee63e57811vandwalle } 148027355a942653264388e909a4276196ee63e57811vandwalle } else { 1481c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 3); 148227355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 148327355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin good candidate seen, bumped hard -> status=" 148427355a942653264388e909a4276196ee63e57811vandwalle + config.autoJoinStatus 1485b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " " + config.configKey(true) + " rssi=(" 14864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 14874dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 14884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 148927355a942653264388e909a4276196ee63e57811vandwalle } 149027355a942653264388e909a4276196ee63e57811vandwalle } 149127355a942653264388e909a4276196ee63e57811vandwalle 149227355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 149327355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 1494931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Network is blacklisted, skip 14954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (DBG) { 14964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptAutoJoin skip blacklisted -> status=" 14974dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 1498b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " " + config.configKey(true) + " rssi=(" 14994dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 15004dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 15014dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 15024dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 150327355a942653264388e909a4276196ee63e57811vandwalle continue; 150427355a942653264388e909a4276196ee63e57811vandwalle } 1505f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 1506ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 150721bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("attemptAutoJoin skip current candidate " 150821bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle + Integer.toString(currentNetId) 1509ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 1510ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1511f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1512f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1513f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 15140eebae7334d6129f7ca1344e4b20199794994358vandwalle boolean isLastSelected = false; 15150eebae7334d6129f7ca1344e4b20199794994358vandwalle if (lastSelectedConfiguration != null && 15160eebae7334d6129f7ca1344e4b20199794994358vandwalle config.configKey().equals(lastSelectedConfiguration)) { 15170eebae7334d6129f7ca1344e4b20199794994358vandwalle isLastSelected = true; 15180eebae7334d6129f7ca1344e4b20199794994358vandwalle } 15190eebae7334d6129f7ca1344e4b20199794994358vandwalle 15200eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.visibility == null) { 15210eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 15220eebae7334d6129f7ca1344e4b20199794994358vandwalle } 15234fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle 15244fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (config.lastRoamingFailure != 0 15254fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && currentConfiguration != null 15264fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && (lastSelectedConfiguration == null 15274fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle || !config.configKey().equals(lastSelectedConfiguration))) { 15284fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // Apply blacklisting for roaming to this config if: 15294fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - the target config had a recent roaming failure 15304fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - we are currently associated 15314fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - the target config is not the last selected 15324fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (now > config.lastRoamingFailure 15334fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && (now - config.lastRoamingFailure) 15344fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle < config.roamingFailureBlackListTimeMilli) { 15354fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (DBG) { 15364fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle logDbg("compareNetwork not switching to " + config.configKey() 15374fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " from current " + currentConfiguration.configKey() 15384fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " because it is blacklisted due to roam failure, " 15394fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " blacklist remain time = " 15404fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + (now - config.lastRoamingFailure) + " ms"); 15414fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 15424fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle continue; 15434fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 15444fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 15454fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle 15461ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount; 15470eebae7334d6129f7ca1344e4b20199794994358vandwalle if ((config.visibility.rssi5 + boost) 15480eebae7334d6129f7ca1344e4b20199794994358vandwalle < mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI 15490eebae7334d6129f7ca1344e4b20199794994358vandwalle && (config.visibility.rssi24 + boost) 15500eebae7334d6129f7ca1344e4b20199794994358vandwalle < mWifiConfigStore.thresholdInitialAutoJoinAttemptMin24RSSI) { 15510eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 15520eebae7334d6129f7ca1344e4b20199794994358vandwalle logDbg("attemptAutoJoin skip due to low visibility -> status=" 15530eebae7334d6129f7ca1344e4b20199794994358vandwalle + config.autoJoinStatus 15540eebae7334d6129f7ca1344e4b20199794994358vandwalle + " key " + config.configKey(true) + " rssi=" 15550eebae7334d6129f7ca1344e4b20199794994358vandwalle + config.visibility.rssi24 + ", " + config.visibility.rssi5 15560eebae7334d6129f7ca1344e4b20199794994358vandwalle + " num=" + config.visibility.num24 15570eebae7334d6129f7ca1344e4b20199794994358vandwalle + ", " + config.visibility.num5); 15580eebae7334d6129f7ca1344e4b20199794994358vandwalle } 15590eebae7334d6129f7ca1344e4b20199794994358vandwalle 1560c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Don't try to autojoin a network that is too far but 1561c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If that configuration is a user's choice however, try anyway 15620eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!isLastSelected) { 15630eebae7334d6129f7ca1344e4b20199794994358vandwalle config.autoJoinBailedDueToLowRssi = true; 15641ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = true; 15658c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 15660eebae7334d6129f7ca1344e4b20199794994358vandwalle } else { 15670eebae7334d6129f7ca1344e4b20199794994358vandwalle // Next time, try to be a bit more aggressive in auto-joining 15680eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.autoJoinUseAggressiveJoinAttemptThreshold 1569dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle < WifiConfiguration.MAX_INITIAL_AUTO_JOIN_RSSI_BOOST 1570dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle && config.autoJoinBailedDueToLowRssi) { 1571dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle config.autoJoinUseAggressiveJoinAttemptThreshold += 4; 15724dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 15738c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 15740eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1575d30127db46224e45554f8964209221bba8ad41d9vandwalle if (config.numNoInternetAccessReports > 0 1576d30127db46224e45554f8964209221bba8ad41d9vandwalle && !isLastSelected 1577d30127db46224e45554f8964209221bba8ad41d9vandwalle && !config.validatedInternetAccess) { 1578d30127db46224e45554f8964209221bba8ad41d9vandwalle // Avoid autoJoining this network because last time we used it, it didn't 1579d30127db46224e45554f8964209221bba8ad41d9vandwalle // have internet access, and we never manage to validate internet access on this 1580d30127db46224e45554f8964209221bba8ad41d9vandwalle // network configuration 15810eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 1582d30127db46224e45554f8964209221bba8ad41d9vandwalle logDbg("attemptAutoJoin skip candidate due to no InternetAccess " 1583d30127db46224e45554f8964209221bba8ad41d9vandwalle + config.configKey(true) 1584d30127db46224e45554f8964209221bba8ad41d9vandwalle + " num reports " + config.numNoInternetAccessReports); 15859f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 15860eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 15878c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 15888c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1589ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1590e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String cur = ""; 1591e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (candidate != null) { 1592e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle cur = " current candidate " + candidate.configKey(); 1593e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1594e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptAutoJoin trying id=" 1595c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Integer.toString(config.networkId) + " " 1596b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + config.configKey(true) 1597e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " status=" + config.autoJoinStatus 1598e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + cur); 1599ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1600f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1601f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 1602f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1603f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1604f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1605453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 16064dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " with " + config.configKey()); 1607f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1608833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(candidate, config); 16092451dbcc4f9641df188326215b204b798eb70c46vandwalle 16102451dbcc4f9641df188326215b204b798eb70c46vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 1611c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 16122451dbcc4f9641df188326215b204b798eb70c46vandwalle // enableNetwork with disableOthers=true WifiManager API 16132451dbcc4f9641df188326215b204b798eb70c46vandwalle // As this is a direct user choice, we strongly prefer this configuration, 16142451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence give +/-100 16152451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((lastSelectedConfiguration != null) 16162451dbcc4f9641df188326215b204b798eb70c46vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 16172451dbcc4f9641df188326215b204b798eb70c46vandwalle // candidate is the last selected configuration, 16182451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 16192451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 16202451dbcc4f9641df188326215b204b798eb70c46vandwalle // by reducing order by -100 16212451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - 100; 16222451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 16232f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers -100 " + candidate.configKey() 16242451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + config.configKey() 16252451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 16262451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 16272451dbcc4f9641df188326215b204b798eb70c46vandwalle } 16282451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if ((lastSelectedConfiguration != null) 16292451dbcc4f9641df188326215b204b798eb70c46vandwalle && config.configKey().equals(lastSelectedConfiguration)) { 16302451dbcc4f9641df188326215b204b798eb70c46vandwalle // config is the last selected configuration, 16312451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 16322451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 16332451dbcc4f9641df188326215b204b798eb70c46vandwalle // by increasing order by +100 16342451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + 100; 16352451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 16362f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers +100 " + config.configKey() 16372451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + candidate.configKey() 16382451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 16392451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 16402451dbcc4f9641df188326215b204b798eb70c46vandwalle } 16412451dbcc4f9641df188326215b204b798eb70c46vandwalle } 16422451dbcc4f9641df188326215b204b798eb70c46vandwalle 1643f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 1644931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Ascending : candidate < config 1645f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1646f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1647f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1648f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1649f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 16502451dbcc4f9641df188326215b204b798eb70c46vandwalle // Now, go thru scan result to try finding a better untrusted network 1651833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if (mNetworkScoreCache != null && mAllowUntrustedConnections) { 1652f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 1653f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 1654f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 1655f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 1656f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 1657f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1658f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1659931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Get current date 16602451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 1661c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int currentScore = -10000; 1662c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // The untrusted network with highest score 1663c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle ScanResult untrustedCandidate = null; 16642451dbcc4f9641df188326215b204b798eb70c46vandwalle // Look for untrusted scored network only if the current candidate is bad 1665c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (isBadCandidate(rssi24, rssi5)) { 1666f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (ScanResult result : scanResultCache.values()) { 1667c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We look only at untrusted networks with a valid SSID 1668c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // A trusted result would have been looked at thru it's Wificonfiguration 16698639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (TextUtils.isEmpty(result.SSID) || !result.untrusted || 16708639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !isOpenNetwork(result)) { 1671c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle continue; 1672c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 16732c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson String quotedSSID = "\"" + result.SSID + "\""; 16742c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains(quotedSSID)) { 16752ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle // SSID had been Forgotten by user, then don't score it 16762ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle continue; 16772ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle } 1678833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if ((nowMs - result.seen) < mScanResultAutoJoinAge) { 1679c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Increment usage count for the network 16802c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson mWifiConnectionStatistics.incrementOrAddUntrusted(quotedSSID, 0, 1); 1681c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 16822c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson boolean isActiveNetwork = currentConfiguration != null 16832c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson && currentConfiguration.SSID.equals(quotedSSID); 168481c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int score = mNetworkScoreCache.getNetworkScore(result, isActiveNetwork); 1685c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (score != WifiNetworkScoreCache.INVALID_NETWORK_SCORE 1686c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle && score > currentScore) { 1687c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Highest score: Select this candidate 1688c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle currentScore = score; 1689c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle untrustedCandidate = result; 1690c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (VDBG) { 1691c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("AutoJoinController: found untrusted candidate " 1692c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + result.SSID 1693c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " RSSI=" + result.level 1694c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " freq=" + result.frequency 1695c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " score=" + score); 1696c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1697f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1698f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1699f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1700f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1701c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (untrustedCandidate != null) { 17028639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // At this point, we have an untrusted network candidate. 17038639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // Create the new ephemeral configuration and see if we should switch over 1704833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate = 1705833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.wifiConfigurationFromScanResult(untrustedCandidate); 1706833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.allowedKeyManagement.set(KeyMgmt.NONE); 1707833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.ephemeral = true; 1708c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1709c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1710b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 17111ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle long lastUnwanted = 17121ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle System.currentTimeMillis() 17131ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle - mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp; 17141ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (candidate == null 17151ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && lastSelectedConfiguration == null 17161ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && currentConfiguration == null 17171ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && didBailDueToWeakRssi 17181ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && (mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp == 0 17191ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle || lastUnwanted > (1000 * 60 * 60 * 24 * 7)) 17201ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle ) { 17211ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // We are bailing out of autojoin although we are seeing a weak configuration, and 17221ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we didn't find another valid candidate 17231ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we are not connected 17241ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - without a user network selection choice 17251ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - ConnectivityService has not triggered an unwanted network disconnect 17261ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // on this device for a week (hence most likely there is no SIM card or cellular) 17271ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // If all those conditions are met, then boost the RSSI of the weak networks 17281ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // that we are seeing so as we will eventually pick one 17291ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount < 10) 17301ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount += 1; 17311ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } else { 17321ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount > 0) 17331ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount -= 1; 17341ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } 17351ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 1736931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1737931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * If candidate is found, check the state of the connection so as 1738931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * to decide if we should be acting on this candidate and switching over 1739931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1740e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle int networkDelta = compareNetwork(candidate, lastSelectedConfiguration); 1741b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (DBG && candidate != null) { 1742b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String doSwitch = ""; 1743b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String current = ""; 1744b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (networkDelta < 0) { 1745b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle doSwitch = " -> not switching"; 1746b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1747b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (currentConfiguration != null) { 17482f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle current = " with current " + currentConfiguration.configKey(); 1749b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1750b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("attemptAutoJoin networkSwitching candidate " 1751b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + candidate.configKey() 1752b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + current 1753c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + " linked=" + (currentConfiguration != null 1754b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle && currentConfiguration.isLinked(candidate)) 1755b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " : delta=" 1756b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + Integer.toString(networkDelta) + " " 1757b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + doSwitch); 1758b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 17594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1760931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1761931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Ask WifiStateMachine permission to switch : 1762931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * if user is currently streaming voice traffic, 1763931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * then we should not be allowed to switch regardless of the delta 1764931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1765b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) { 1766b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mStaStaSupported) { 1767b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("mStaStaSupported --> error do nothing now "); 1768b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1769b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) { 1770b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING; 1771b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1772b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING; 1773b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1774b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1775b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto connect with netId " 1776b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(candidate.networkId) 1777b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " to " + candidate.configKey()); 1778b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 17792451dbcc4f9641df188326215b204b798eb70c46vandwalle if (didOverride) { 17802451dbcc4f9641df188326215b204b798eb70c46vandwalle candidate.numScorerOverrideAndSwitchedNetwork++; 17812451dbcc4f9641df188326215b204b798eb70c46vandwalle } 1782c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle candidate.numAssociation++; 1783e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoJoinAttempt++; 17849f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 17852c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson if (candidate.ephemeral) { 17862c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson // We found a new candidate that we are going to connect to, then 17872c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson // increase its connection count 17882c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson mWifiConnectionStatistics. 17892c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson incrementOrAddUntrusted(candidate.SSID, 1, 0); 17902c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson } 17912c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson 17922f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (candidate.BSSID == null || candidate.BSSID.equals("any")) { 17932f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // First step we selected the configuration we want to connect to 17942f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Second step: Look for the best Scan result for this configuration 17952f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // TODO this algorithm should really be done in one step 17962f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1797833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1798833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, candidate, mScanResultAutoJoinAge, null); 17992f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && currentBSSID != null 18002f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 18012f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Sanity, we were already asociated to that candidate 18022f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle roamCandidate = null; 18032f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 18042f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && roamCandidate.is5GHz()) { 18052f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // If the configuration hasn't a default BSSID selected, and the best 18062f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // candidate is 5GHZ, then select this candidate so as WifiStateMachine and 18072f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // supplicant will pick it first 18082f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle candidate.autoJoinBSSID = roamCandidate.BSSID; 18092f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) { 18102f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("AutoJoinController: lock to 5GHz " 18112f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + candidate.autoJoinBSSID 18122f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " RSSI=" + roamCandidate.level 18132f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " freq=" + roamCandidate.frequency); 18142f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 1815448c9536a302c58a79e271b1721c08b8882f800evandwalle } else { 1816448c9536a302c58a79e271b1721c08b8882f800evandwalle // We couldnt find a roam candidate 1817448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.autoJoinBSSID = "any"; 18189f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 18199f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1820448c9536a302c58a79e271b1721c08b8882f800evandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 1821448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.networkId, networkSwitchType, candidate); 182268fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 18234dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1824b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1826b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (networkSwitchType == AUTO_JOIN_IDLE) { 1827e67ec726c07410073575473c0f50dc737629f5davandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1828931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Attempt same WifiConfiguration roaming 1829833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1830833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, currentConfiguration, mScanResultAutoJoinAge, currentBSSID); 1831e67ec726c07410073575473c0f50dc737629f5davandwalle /** 1832e67ec726c07410073575473c0f50dc737629f5davandwalle * TODO: (post L initial release) 1833e67ec726c07410073575473c0f50dc737629f5davandwalle * consider handling linked configurations roaming (i.e. extended Roaming) 1834e67ec726c07410073575473c0f50dc737629f5davandwalle * thru the attemptRoam function which makes use of the RSSI roaming threshold. 1835e67ec726c07410073575473c0f50dc737629f5davandwalle * At the moment, extended roaming is only handled thru the attemptAutoJoin() 1836e67ec726c07410073575473c0f50dc737629f5davandwalle * function which compare configurations. 1837e67ec726c07410073575473c0f50dc737629f5davandwalle * 1838e67ec726c07410073575473c0f50dc737629f5davandwalle * The advantage of making use of attemptRoam function is that this function 1839e67ec726c07410073575473c0f50dc737629f5davandwalle * will looks at all the BSSID of each configurations, instead of only looking 1840e67ec726c07410073575473c0f50dc737629f5davandwalle * at WifiConfiguration.visibility which keeps trackonly of the RSSI/band of the 1841e67ec726c07410073575473c0f50dc737629f5davandwalle * two highest BSSIDs. 1842e67ec726c07410073575473c0f50dc737629f5davandwalle */ 1843e67ec726c07410073575473c0f50dc737629f5davandwalle // Attempt linked WifiConfiguration roaming 1844e67ec726c07410073575473c0f50dc737629f5davandwalle /* if (currentConfiguration != null 1845e67ec726c07410073575473c0f50dc737629f5davandwalle && currentConfiguration.linkedConfigurations != null) { 1846e67ec726c07410073575473c0f50dc737629f5davandwalle for (String key : currentConfiguration.linkedConfigurations.keySet()) { 1847e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration link = mWifiConfigStore.getWifiConfiguration(key); 1848e67ec726c07410073575473c0f50dc737629f5davandwalle if (link != null) { 1849833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle roamCandidate = attemptRoam(roamCandidate, link, mScanResultAutoJoinAge, 1850e67ec726c07410073575473c0f50dc737629f5davandwalle currentBSSID); 1851e67ec726c07410073575473c0f50dc737629f5davandwalle } 1852e67ec726c07410073575473c0f50dc737629f5davandwalle } 1853e67ec726c07410073575473c0f50dc737629f5davandwalle }*/ 1854e67ec726c07410073575473c0f50dc737629f5davandwalle if (roamCandidate != null && currentBSSID != null 1855e67ec726c07410073575473c0f50dc737629f5davandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 1856e67ec726c07410073575473c0f50dc737629f5davandwalle roamCandidate = null; 1857e67ec726c07410073575473c0f50dc737629f5davandwalle } 18582f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && mWifiStateMachine.shouldSwitchNetwork(999)) { 1859b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1860b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto roam with netId " 1861b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(currentConfiguration.networkId) 1862b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " " + currentConfiguration.configKey() + " to BSSID=" 1863b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + roamCandidate.BSSID + " freq=" + roamCandidate.frequency 18641ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle + " RSSI=" + roamCandidate.level); 1865b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1866b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_ROAMING; 1867e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoRoamAttempt++; 1868e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 1869b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM, 1870b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle currentConfiguration.networkId, 1, roamCandidate); 187168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 1872f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1873f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1874b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType)); 187568fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return found; 1876f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1877f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 1878f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1879