WifiAutoJoinController.java revision 93a1fddee50a244d31036cddae6b7db6630fd93d
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; 25c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalleimport android.text.TextUtils; 26f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log; 27f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 280c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.ArrayList; 29f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Iterator; 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 31f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 32f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 33f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 34f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 35f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 36f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 37f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 39f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 40f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 41f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 42f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 43f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 44f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 45f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 46f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 47f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 48f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 50ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean DBG = false; 51ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 53f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 54c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle public static int mScanResultMaximumAge = 40000; /* milliseconds unit */ 55833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle public static int mScanResultAutoJoinAge = 5000; /* milliseconds unit */ 56c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 57453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 58f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 59f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private HashMap<String, ScanResult> scanResultCache = 60f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle new HashMap<String, ScanResult>(); 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 62c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle private WifiConnectionStatistics mWifiConnectionStatistics; 63c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 648639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** Whether to allow connections to untrusted networks. */ 658639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean mAllowUntrustedConnections = false; 668639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 67c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle /* for debug purpose only : the untrusted SSID we would be connected to if we had VPN */ 68c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle String lastUntrustedBSSID = null; 69c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 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 78b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_IDLE = 0; 79b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_ROAMING = 1; 80b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_EXTENDED_ROAMING = 2; 81b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3; 82b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 8397b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle public static final int HIGH_THRESHOLD_MODIFIER = 5; 8497b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle 851ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // Below are AutoJoin wide parameters indicating if we should be aggressive before joining 861ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // weak network. Note that we cannot join weak network that are going to be marked as unanted by 871ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // ConnectivityService because this will trigger link flapping. 881ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 891ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * There was a non-blacklisted configuration that we bailed from because of a weak signal 901ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 911ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle boolean didBailDueToWeakRssi = false; 921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 931ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * number of time we consecutively bailed out of an eligible network because its signal 941ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * was too weak 951ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 961ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int weakRssiBailCount = 0; 971ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 98f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 99c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle WifiConnectionStatistics st, WifiNative n) { 100f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 101f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 102f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 103f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 104f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 105c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics = st; 10621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle scoreManager = 10721bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 108f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 109f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 110f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 111f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 112f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 113f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 115f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 122ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 123ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (verbose > 0 ) { 124abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = true; 125ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 126ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 127abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = false; 128ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 129ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 130ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 131ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 132931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 133931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Flush out scan results older than mScanResultMaximumAge 134ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * 135931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 138931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle delay = mScanResultMaximumAge; // Something sane 139f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 140b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long milli = System.currentTimeMillis(); 141f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 142f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 143f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 144f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 145f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 146f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Iterator<HashMap.Entry<String,ScanResult>> iter = scanResultCache.entrySet().iterator(); 147f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 148f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle HashMap.Entry<String,ScanResult> entry = iter.next(); 149f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult result = entry.getValue(); 150f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 151f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.seen + delay) < milli) { 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 155f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 157be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int addToScanCache(List<ScanResult> scanList) { 158be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown = 0; // Record number of scan results we knew about 159be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiConfiguration associatedConfig = null; 1607b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle boolean didAssociate = false; 1618242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1630c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 1640c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for(ScanResult result: scanList) { 1661fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (result.SSID == null) continue; 167c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 168c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Make sure we record the last time we saw this result 169f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.seen = System.currentTimeMillis(); 170f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 171c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Fetch the previous instance for this result 172f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult sr = scanResultCache.get(result.BSSID); 173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (sr != null) { 174931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If there was a previous cache result for this BSSID, average the RSSI values 175c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge); 176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 177c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Remove the previous Scan Result - this is not necessary 178f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.remove(result.BSSID); 179e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 180e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 181e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 182e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle WifiKey wkey; 183e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle // Quoted SSIDs are the only one valid at this stage 184e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle try { 185e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 186e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } catch (IllegalArgumentException e) { 187e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID + 188e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle "] ->skipping this network"); 189e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle wkey = null; 190e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 191e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (wkey != null) { 192e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle NetworkKey nkey = new NetworkKey(wkey); 193e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle //if we don't know this scan result then request a score from the scorer 194e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle unknownScanResults.add(nkey); 195e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 196e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 1977b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 1987b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 1997b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 200e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 2017b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is not scored"); 202e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 2030c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 204e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 2057b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 2067b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 2077b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 208e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 209e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 2107b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is scored : " + score); 2110c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 212f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 213f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 214e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // scanResultCache.put(result.BSSID, new ScanResult(result)); 215e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle scanResultCache.put(result.BSSID, result); 216be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // Add this BSSID to the scanResultCache of a Saved WifiConfiguration 2177b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = mWifiConfigStore.updateSavedNetworkHistory(result); 218f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 219be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // If not successful, try to associate this BSSID to an existing Saved WifiConfiguration 2207b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (!didAssociate) { 221be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // We couldn't associate the scan result to a Saved WifiConfiguration 222c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Hence it is untrusted 223c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.untrusted = true; 224f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.associateWithConfiguration(result); 2251fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (associatedConfig != null && associatedConfig.SSID != null) { 226f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 227f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("addToScanCache save associated config " 2288242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + associatedConfig.SSID + " with " + result.SSID 2298242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " status " + associatedConfig.autoJoinStatus 2308242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " reason " + associatedConfig.disableReason 2318242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " tsp " + associatedConfig.blackListTimestamp 2328242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " was " + (now - associatedConfig.blackListTimestamp)); 233f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 234be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle mWifiStateMachine.sendMessage( 235be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiStateMachine.CMD_AUTO_SAVE_NETWORK, associatedConfig); 2367b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = true; 237f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2380d616ef3bf635dff8722e064c0be842676390ed8vandwalle } else { 2390d616ef3bf635dff8722e064c0be842676390ed8vandwalle // If the scan result has been blacklisted fir 18 hours -> unblacklist 2400d616ef3bf635dff8722e064c0be842676390ed8vandwalle if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { 2410d616ef3bf635dff8722e064c0be842676390ed8vandwalle result.setAutoJoinStatus(ScanResult.ENABLED); 2420d616ef3bf635dff8722e064c0be842676390ed8vandwalle } 243f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2447b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (didAssociate) { 245be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown++; 246a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate ++; 247a0708b09ad17b086c008ab100aec7143d7613c80vandwalle } else { 248a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate = 0; 249be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 250f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2510c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 2520c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 2530c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 2540c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 255931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Kick the score manager, we will get updated scores asynchronously 2560c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 2570c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 258be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 259f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 260f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 261f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 2620888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle logDbg(message, false); 263ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 264ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 265ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 266ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 2672f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle Log.e(TAG, message + " stack:" 268ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 269ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 270ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 271ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 272ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 2732f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle Log.e(TAG, message); 274ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 275f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 277931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Called directly from WifiStateMachine 278be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int newSupplicantResults(boolean doAutoJoin) { 279be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown; 280e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle List<ScanResult> scanList = mWifiStateMachine.getScanResultsListNoCopyUnsync(); 281be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown = addToScanCache(scanList); 282f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 283be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle if (DBG) { 284be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) 2852f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " known=" + numScanResultsKnown + " " 2869f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle + doAutoJoin); 287be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 2887806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (doAutoJoin) { 2897806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle attemptAutoJoin(); 2907806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 291005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 292be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 293f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 294f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 295f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 296931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 297931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Not used at the moment 298f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 299f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 300f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 301f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 302f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 303f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 304f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<ScanResult> scanList = null;//mWifiScanner.syncGetScanResultsList(); 305f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 306f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 307f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 308f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 309f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 310005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 311f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 312f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 313931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 314931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * network link quality changed, called directly from WifiTrafficPoller, 315931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * or by listening to Link Quality intent 316931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 317f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 318f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 319f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 320f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 321931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 322f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 323f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 324f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 325f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 326b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * Negatve return values from this functions are meaningless per se, just trying to 327b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * keep them distinct for debug purpose (i.e. -1, -2 etc...) 328931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 329e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle private int compareNetwork(WifiConfiguration candidate, 330e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String lastSelectedConfiguration) { 331b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (candidate == null) 332b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -3; 333b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 334f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 335b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentNetwork == null) { 336c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Return any absurdly high score, if we are not connected there is no current 337c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // network to... 338b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return 1000; 339b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 340f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 341f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 342b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -2; 343f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 344f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 345b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (DBG) { 346e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("compareNetwork will compare " + candidate.configKey() 347e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " with current " + currentNetwork.configKey()); 348b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 349833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 350e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 351e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 352e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 353e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // enableNetwork with disableOthers=true WifiManager API 354e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // As this is a direct user choice, we strongly prefer this configuration, 355e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // hence give +/-100 356e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if ((lastSelectedConfiguration != null) 357e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && currentNetwork.configKey().equals(lastSelectedConfiguration)) { 358e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // currentNetwork is the last selected configuration, 359e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 360e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 361e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by reducing order by -100 362e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order - 100; 363e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 364e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers -100 " + currentNetwork.configKey() 365e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + candidate.configKey() 366e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 367e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 368e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 369e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } else if ((lastSelectedConfiguration != null) 370e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 371e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // candidate is the last selected configuration, 372e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 373e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 374e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by increasing order by +100 375e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order + 100; 376e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 377e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers +100 " + candidate.configKey() 378e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + currentNetwork.configKey() 379e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 380e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 381e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 382e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 383e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 384ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle return order; 385f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 386f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 387ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 388ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 389ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 390ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 391ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 392ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 39362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 394ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 395ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 396ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param connect : if the update includes a connect 397931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 39862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 399f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 400f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 401c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + " no selected configuration!"); 402f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 403f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 404f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 405e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 406c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + 407c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle " no SSID in selected configuration!"); 408e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 409e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 410e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 41162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 412931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable autojoin for this network, 41362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 41427355a942653264388e909a4276196ee63e57811vandwalle selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 41562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 416e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle selected.dirty = true; 41762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 418f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 419992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG && userTriggered) { 420f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 421ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 422f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 423992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(selected.connectChoices.size()) 424992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 425f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 426ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 427992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(netId) 428992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 429f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 430f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 431f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 432ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 433ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 4342451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice = 0; 435c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int size = 0; 4369f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 4379f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // Reset the triggered disabled count, because user wanted to connect to this 4389f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // configuration, and we were not. 4399f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableLowRSSI = 0; 4409f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableBadRSSI = 0; 4419f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableNotHighRSSI = 0; 4429f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredJoinAttempts++; 4439f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 44462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 44562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 446c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (networks != null) size = networks.size(); 447c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory found " + size + " networks"); 44862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 44962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 450992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG) { 451992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle logDbg("updateConfigurationHistory got " + config.SSID + " nid=" 452992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(config.networkId)); 453992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 454f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 45562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 456ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 45762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 45862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 459f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 4602451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare RSSI values so as to evaluate the strength of the user preference 4612451dbcc4f9641df188326215b204b798eb70c46vandwalle int order = compareWifiConfigurationsRSSI(config, selected, null); 4622451dbcc4f9641df188326215b204b798eb70c46vandwalle 4632451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order < -30) { 4642451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is worse than the visible configuration 4652451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a strong choice so as autojoin cannot override this 4662451dbcc4f9641df188326215b204b798eb70c46vandwalle // for instance, the user has select a network 4672451dbcc4f9641df188326215b204b798eb70c46vandwalle // with 1 bar over a network with 3 bars... 4682451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 60; 4692451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -20) { 4702451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 50; 4712451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -10) { 4722451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 40; 4732f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else if (order < 20) { 4742451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is about same or has a slightly better RSSI 4752451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a weaker choice, here a difference of at least +/-30 in 4762451dbcc4f9641df188326215b204b798eb70c46vandwalle // RSSI comparison triggered by autoJoin will override the choice 4772451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 30; 4782f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else { 4792451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is better than the visible configuration 4802451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence we do not know if the user prefers this configuration strongly 4812451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; 48262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 483f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 484931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // The selected configuration was preferred over a recently seen config 485931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // hence remember the user's choice: 486931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // add the recently seen config to the selected's connectChoices array 487ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 488ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (selected.connectChoices == null) { 489ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle selected.connectChoices = new HashMap<String, Integer>(); 490ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 491ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 492ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory add a choice " + selected.configKey(true) 4930888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle + " over " + config.configKey(true) 4942451dbcc4f9641df188326215b204b798eb70c46vandwalle + " choice " + Integer.toString(choice)); 495cf5b8eb8a08c45bd4a82f1f4bb789c8a1b08744fvandwalle 4962451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer currentChoice = selected.connectChoices.get(config.configKey(true)); 4972f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (currentChoice != null) { 4982f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // User has made this choice multiple time in a row, so bump up a lot 4992f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle choice += currentChoice.intValue(); 5002451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5012f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Add the visible config to the selected's connect choice list 5022f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle selected.connectChoices.put(config.configKey(true), choice); 503f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 50462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 505ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 506ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 50762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 508ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 509931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected from the recently seen config's connectChoice list 51062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 5110888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 5120888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (selected.linkedConfigurations != null) { 513931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected's linked configuration from the 514931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // recently seen config's connectChoice list 5150888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle for (String key : selected.linkedConfigurations.keySet()) { 5160888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle config.connectChoices.remove(key); 5170888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 5180888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 51962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 520ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 521ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 5222451dbcc4f9641df188326215b204b798eb70c46vandwalle // We haven't found the configuration that the user just selected in our 5232451dbcc4f9641df188326215b204b798eb70c46vandwalle // scan cache. 5242451dbcc4f9641df188326215b204b798eb70c46vandwalle // In that case we will need a new scan before attempting to connect to this 5252451dbcc4f9641df188326215b204b798eb70c46vandwalle // configuration anyhow and thus we can process the scan results then. 526ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 527ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + selected.configKey()); 52862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 529f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 53062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 53162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 532ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 53362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 53462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 535f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 536f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 537992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle 538931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // TODO: write only if something changed 539992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (userTriggered || connect) { 540005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 541992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 542f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 543f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5442451dbcc4f9641df188326215b204b798eb70c46vandwalle int getConnectChoice(WifiConfiguration source, WifiConfiguration target) { 5452451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer choice = null; 5462451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source == null || target == null) { 5472451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 548f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 549f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5502451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source.connectChoices != null 5512451dbcc4f9641df188326215b204b798eb70c46vandwalle && source.connectChoices.containsKey(target.configKey(true))) { 5522451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = source.connectChoices.get(target.configKey(true)); 5532451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (source.linkedConfigurations != null) { 554f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 555f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 556f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 557f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 5582451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = config.connectChoices.get(target.configKey(true)); 559f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 560f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 561f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 5622451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5632451dbcc4f9641df188326215b204b798eb70c46vandwalle 5642451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice == null) { 5652451dbcc4f9641df188326215b204b798eb70c46vandwalle //We didn't find the connect choice 5662451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 5672451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 5682451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice.intValue() < 0) { 5692451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; // Compatibility with older files 5702451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5712451dbcc4f9641df188326215b204b798eb70c46vandwalle return choice.intValue(); 5722451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5732451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5742451dbcc4f9641df188326215b204b798eb70c46vandwalle 5752451dbcc4f9641df188326215b204b798eb70c46vandwalle 5769f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle int getScoreFromVisibility(WifiConfiguration.Visibility visibility, int rssiBoost, String dbg) { 5772451dbcc4f9641df188326215b204b798eb70c46vandwalle int rssiBoost5 = 0; 5782451dbcc4f9641df188326215b204b798eb70c46vandwalle int score = 0; 5794dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 5802451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 5812451dbcc4f9641df188326215b204b798eb70c46vandwalle * Boost RSSI value of 5GHz bands iff the base value is better than threshold 5822451dbcc4f9641df188326215b204b798eb70c46vandwalle * This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas 5832451dbcc4f9641df188326215b204b798eb70c46vandwalle * we prefer 2.4GHz otherwise. 5842451dbcc4f9641df188326215b204b798eb70c46vandwalle * Note that 2.4GHz doesn't need a boost since at equal power the RSSI is typically 585e67ec726c07410073575473c0f50dc737629f5davandwalle * at least 6-10 dB higher 5862451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 5879f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle rssiBoost5 = rssiBoostFrom5GHzRssi(visibility.rssi5, dbg+"->"); 5882451dbcc4f9641df188326215b204b798eb70c46vandwalle 5892451dbcc4f9641df188326215b204b798eb70c46vandwalle // Select which band to use so as to score a 5902451dbcc4f9641df188326215b204b798eb70c46vandwalle if (visibility.rssi5 + rssiBoost5 > visibility.rssi24) { 5912451dbcc4f9641df188326215b204b798eb70c46vandwalle // Prefer a's 5GHz 5922451dbcc4f9641df188326215b204b798eb70c46vandwalle score = visibility.rssi5 + rssiBoost5 + rssiBoost; 5932451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 5942451dbcc4f9641df188326215b204b798eb70c46vandwalle // Prefer a's 2.4GHz 5952451dbcc4f9641df188326215b204b798eb70c46vandwalle score = visibility.rssi24 + rssiBoost; 596f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 5972451dbcc4f9641df188326215b204b798eb70c46vandwalle 5982451dbcc4f9641df188326215b204b798eb70c46vandwalle return score; 599f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 600f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6012451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50] 6022451dbcc4f9641df188326215b204b798eb70c46vandwalle // The result represents "approximately" an RSSI difference measured in dBM 6032451dbcc4f9641df188326215b204b798eb70c46vandwalle // Adjusted with various parameters: 6042451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) current network gets a +15 boost 6052451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) 5GHz signal, if they are strong enough, get a +15 or +25 boost, representing the 6062451dbcc4f9641df188326215b204b798eb70c46vandwalle // fact that at short range we prefer 5GHz band as it is cleaner of interference and 6072451dbcc4f9641df188326215b204b798eb70c46vandwalle // provides for wider channels 6082451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b, 6092451dbcc4f9641df188326215b204b798eb70c46vandwalle String currentConfiguration) { 610f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 6112451dbcc4f9641df188326215b204b798eb70c46vandwalle 6122451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost used so as to favor current config 6132451dbcc4f9641df188326215b204b798eb70c46vandwalle int aRssiBoost = 0; 6142451dbcc4f9641df188326215b204b798eb70c46vandwalle int bRssiBoost = 0; 6152451dbcc4f9641df188326215b204b798eb70c46vandwalle 6162451dbcc4f9641df188326215b204b798eb70c46vandwalle int scoreA; 6172451dbcc4f9641df188326215b204b798eb70c46vandwalle int scoreB; 6182451dbcc4f9641df188326215b204b798eb70c46vandwalle 6192451dbcc4f9641df188326215b204b798eb70c46vandwalle // Retrieve the visibility 620f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 621f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 622f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 6232451dbcc4f9641df188326215b204b798eb70c46vandwalle // Error visibility wasn't set 624b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations NULL band status!"); 625f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 626f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 6272451dbcc4f9641df188326215b204b798eb70c46vandwalle 6282451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis, boost RSSI of current configuration 6292451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != currentConfiguration) { 6302451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(currentConfiguration)) { 63193a1fddee50a244d31036cddae6b7db6630fd93dvandwalle aRssiBoost = mWifiConfigStore.currentNetworkBoost; 6322451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(currentConfiguration)) { 63393a1fddee50a244d31036cddae6b7db6630fd93dvandwalle bRssiBoost = mWifiConfigStore.currentNetworkBoost; 6342451dbcc4f9641df188326215b204b798eb70c46vandwalle } 6352451dbcc4f9641df188326215b204b798eb70c46vandwalle } 6362451dbcc4f9641df188326215b204b798eb70c46vandwalle 6372451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 638b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI: " + a.configKey() 639c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " " + Integer.toString(astatus.rssi24) 640c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + "," + Integer.toString(astatus.rssi5) 6412451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(aRssiBoost) 642c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " " + b.configKey() + " " 643c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi24) + "," 644c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi5) 6452451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(bRssiBoost) 6462451dbcc4f9641df188326215b204b798eb70c46vandwalle ); 647f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 6482451dbcc4f9641df188326215b204b798eb70c46vandwalle 6499f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle scoreA = getScoreFromVisibility(astatus, aRssiBoost, a.configKey()); 6509f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle scoreB = getScoreFromVisibility(bstatus, bRssiBoost, b.configKey()); 6512451dbcc4f9641df188326215b204b798eb70c46vandwalle 6522451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare a and b 6532451dbcc4f9641df188326215b204b798eb70c46vandwalle // If a score is higher then a > b and the order is descending (negative) 6542451dbcc4f9641df188326215b204b798eb70c46vandwalle // If b score is higher then a < b and the order is ascending (positive) 6552451dbcc4f9641df188326215b204b798eb70c46vandwalle order = scoreB - scoreA; 6562451dbcc4f9641df188326215b204b798eb70c46vandwalle 6572451dbcc4f9641df188326215b204b798eb70c46vandwalle // Normalize the order to [-50, +50] 6582451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 50) order = 50; 6592451dbcc4f9641df188326215b204b798eb70c46vandwalle else if (order < -50) order = -50; 6602451dbcc4f9641df188326215b204b798eb70c46vandwalle 6612451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 6622451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 6632451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 0) { 6642451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; // Ascending 6652451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < 0) { 6662451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; // Descending 6672451dbcc4f9641df188326215b204b798eb70c46vandwalle } 668b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI " + a.configKey() 6692451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 6702451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 6712451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 6722451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 673e67ec726c07410073575473c0f50dc737629f5davandwalle + " scorea=" + scoreA 6742451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 6752451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 6762451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 6772451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 6782451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 679e67ec726c07410073575473c0f50dc737629f5davandwalle + " scoreb=" + scoreB 6802451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + order); 6812451dbcc4f9641df188326215b204b798eb70c46vandwalle } 6822451dbcc4f9641df188326215b204b798eb70c46vandwalle 683f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 684f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 685f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 686833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /** 687833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * b/18490330 only use scorer for untrusted networks 688833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * 6892451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsWithScorer(WifiConfiguration a, WifiConfiguration b) { 6902451dbcc4f9641df188326215b204b798eb70c46vandwalle 69181c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean aIsActive = false; 69281c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean bIsActive = false; 6932451dbcc4f9641df188326215b204b798eb70c46vandwalle 6942451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis : boost RSSI of current configuration before 6952451dbcc4f9641df188326215b204b798eb70c46vandwalle // looking up the score 6962451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != mCurrentConfigurationKey) { 6972451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(mCurrentConfigurationKey)) { 69881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson aIsActive = true; 6992451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(mCurrentConfigurationKey)) { 70081c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson bIsActive = true; 7012451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7022451dbcc4f9641df188326215b204b798eb70c46vandwalle } 703833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreA = getConfigNetworkScore(a, mScanResultAutoJoinAge, aIsActive); 704833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreB = getConfigNetworkScore(b, mScanResultAutoJoinAge, bIsActive); 7052451dbcc4f9641df188326215b204b798eb70c46vandwalle 7062451dbcc4f9641df188326215b204b798eb70c46vandwalle // Both configurations need to have a score for the scorer to be used 7072451dbcc4f9641df188326215b204b798eb70c46vandwalle // ...and the scores need to be different:-) 7082451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA == WifiNetworkScoreCache.INVALID_NETWORK_SCORE 7092451dbcc4f9641df188326215b204b798eb70c46vandwalle || scoreB == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 710e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 711b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer no-scores: " 712e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + a.configKey() 713e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " " 714e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + b.configKey()); 715e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 7162451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 7172451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7182451dbcc4f9641df188326215b204b798eb70c46vandwalle 7192451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 7202451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 7212451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA < scoreB) { 7222451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; 7232451dbcc4f9641df188326215b204b798eb70c46vandwalle } if (scoreA > scoreB) { 7242451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; 7252451dbcc4f9641df188326215b204b798eb70c46vandwalle } 726b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer " + a.configKey() 7272451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 7282451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 7292451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 7302451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 731e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreA 7322451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 7332451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 7342451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 7352451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 7362451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 737e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreB 7382451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + Integer.toString(scoreB - scoreA)); 7392451dbcc4f9641df188326215b204b798eb70c46vandwalle } 740c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 7412451dbcc4f9641df188326215b204b798eb70c46vandwalle // If scoreA > scoreB, the comparison is descending hence the return value is negative 7422451dbcc4f9641df188326215b204b798eb70c46vandwalle return scoreB - scoreA; 7432451dbcc4f9641df188326215b204b798eb70c46vandwalle } 744833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 7452451dbcc4f9641df188326215b204b798eb70c46vandwalle 746f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 747f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 748f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 749f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 750453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 751453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 752453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 7532451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((a.linkedConfigurations.get(b.configKey(true)) != null) 7542451dbcc4f9641df188326215b204b798eb70c46vandwalle && (b.linkedConfigurations.get(a.configKey(true)) != null)) { 755f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 756f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 757f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 758f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 759f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 760f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 761b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + b.configKey() 762453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 763f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 764931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return 1; // b is of higher priority - ascending 765f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 766f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 767f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 768b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + a.configKey() 769453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 770f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 771931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return -1; // a is of higher priority - descending 772f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 773f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 7742451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply RSSI, in the range [-5, +5] 7752451dbcc4f9641df188326215b204b798eb70c46vandwalle // after band adjustment, +n difference roughly corresponds to +10xn dBm 7762451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + compareWifiConfigurationsRSSI(a, b, mCurrentConfigurationKey); 777f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 7782451dbcc4f9641df188326215b204b798eb70c46vandwalle // If the configurations are not linked, compare by user's choice, only a 7792451dbcc4f9641df188326215b204b798eb70c46vandwalle // very high RSSI difference can then override the choice 7802451dbcc4f9641df188326215b204b798eb70c46vandwalle if (!linked) { 7812451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice; 782f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 7832451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(a, b); 7842451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 785931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 7862451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - choice; 787f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 788b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + a.configKey() 789453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 790b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " due to user choice of " + choice 791b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order -> " + Integer.toString(order)); 792f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7932451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7942451dbcc4f9641df188326215b204b798eb70c46vandwalle 7952451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(b, a); 7962451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 797931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 7982451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + choice; 7994dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 800b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + b.configKey() + " over " 801b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + a.configKey() + " due to user choice of " + choice 802b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order ->" + Integer.toString(order)); 803f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 804f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 805f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 806ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 807f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 808931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // We don't know anything - pick the last seen i.e. K behavior 809931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // we should do this only for recently picked configurations 810f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 811931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 8122451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 813b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers -1 " + a.configKey() + " over " 814453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 815f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 816f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 817f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 818f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 819931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 8202451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 821b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers +1 " + b.configKey() + " over " 822453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 823f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 8242451dbcc4f9641df188326215b204b798eb70c46vandwalle order = 1; 825f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 826f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 827f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 828f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 829931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if (order > 0) { 830f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 831931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } else if (order < 0) { 832f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 833931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } 834f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8352451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 836b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("compareWifiConfigurations: " + a.configKey() + sorder 837453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 838f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 839f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 840f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 841f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 842f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 843c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle boolean isBadCandidate(int rssi5, int rssi24) { 844c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle return (rssi5 < -80 && rssi24 < -90); 845c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 846c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 847833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /* 848c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int compareWifiConfigurationsTop(WifiConfiguration a, WifiConfiguration b) { 849c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int scorerOrder = compareWifiConfigurationsWithScorer(a, b); 850c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int order = compareWifiConfigurations(a, b); 851c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 852c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder * order < 0) { 853b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (VDBG) { 854b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" -> compareWifiConfigurationsTop: " + 855b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle "scorer override " + scorerOrder + " " + order); 856b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 857c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // For debugging purpose, remember that an override happened 858c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // during that autojoin Attempt 859c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = true; 860c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle a.numScorerOverride++; 861c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle b.numScorerOverride++; 862c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 863c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 864c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder != 0) { 865c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If the scorer came up with a result then use the scorer's result, else use 866c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // the order provided by the base comparison function 867c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle order = scorerOrder; 868c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 869c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle return order; 870c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 871833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 872c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 8739f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle public int rssiBoostFrom5GHzRssi(int rssi, String dbg) { 8740eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!mWifiConfigStore.enable5GHzPreference) { 8750eebae7334d6129f7ca1344e4b20199794994358vandwalle return 0; 8760eebae7334d6129f7ca1344e4b20199794994358vandwalle } 877e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 8780eebae7334d6129f7ca1344e4b20199794994358vandwalle > mWifiConfigStore.bandPreferenceBoostThreshold5) { 879e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 2 dB for each point 880e67ec726c07410073575473c0f50dc737629f5davandwalle // Start boosting at -65 881e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 20 if above -55 882e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 40 if abore -45 8830eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferenceBoostFactor5 8840eebae7334d6129f7ca1344e4b20199794994358vandwalle *(rssi - mWifiConfigStore.bandPreferenceBoostThreshold5); 885e67ec726c07410073575473c0f50dc737629f5davandwalle if (boost > 50) { 886e67ec726c07410073575473c0f50dc737629f5davandwalle // 50 dB boost is set so as to overcome the hysteresis of +20 plus a difference of 887e67ec726c07410073575473c0f50dc737629f5davandwalle // 25 dB between 2.4 and 5GHz band. This allows jumping from 2.4 to 5GHz 888e67ec726c07410073575473c0f50dc737629f5davandwalle // consistently 889e67ec726c07410073575473c0f50dc737629f5davandwalle boost = 50; 890e67ec726c07410073575473c0f50dc737629f5davandwalle } 8919f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle if (VDBG && dbg != null) { 892b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" " + dbg + ": rssi5 " + rssi + " boost " + boost); 8939f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 894e67ec726c07410073575473c0f50dc737629f5davandwalle return boost; 895e67ec726c07410073575473c0f50dc737629f5davandwalle } 896e67ec726c07410073575473c0f50dc737629f5davandwalle 897e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 8980eebae7334d6129f7ca1344e4b20199794994358vandwalle < mWifiConfigStore.bandPreferencePenaltyThreshold5) { 8990eebae7334d6129f7ca1344e4b20199794994358vandwalle // penalize if < -75 9000eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferencePenaltyFactor5 9010eebae7334d6129f7ca1344e4b20199794994358vandwalle *(rssi - mWifiConfigStore.bandPreferencePenaltyThreshold5); 9020eebae7334d6129f7ca1344e4b20199794994358vandwalle return boost; 903e67ec726c07410073575473c0f50dc737629f5davandwalle } 904e67ec726c07410073575473c0f50dc737629f5davandwalle return 0; 905e67ec726c07410073575473c0f50dc737629f5davandwalle } 906c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /** 907e67ec726c07410073575473c0f50dc737629f5davandwalle * attemptRoam() function implements the core of the same SSID switching algorithm 908e67ec726c07410073575473c0f50dc737629f5davandwalle * 909e67ec726c07410073575473c0f50dc737629f5davandwalle * Run thru all recent scan result of a WifiConfiguration and select the 910e67ec726c07410073575473c0f50dc737629f5davandwalle * best one. 911c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle */ 912e67ec726c07410073575473c0f50dc737629f5davandwalle public ScanResult attemptRoam(ScanResult a, 913e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration current, int age, String currentBSSID) { 914b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current == null) { 915b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 916b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam not associated"); 917b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 918e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 9194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 920b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current.scanResultCache == null) { 921b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 922b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam no scan cache"); 923b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 924e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 9254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 926b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle if (current.scanResultCache.size() > 6) { 927b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 928c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam scan cache size " 929c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + current.scanResultCache.size() + " --> bail"); 930b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 931931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Implement same SSID roaming only for configurations 932c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // that have less than 4 BSSIDs 933e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 9344dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 935b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 9362f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (current.BSSID != null && !current.BSSID.equals("any")) { 937b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 9382f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("attemptRoam() BSSID is set " 9392f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + current.BSSID + " -> bail"); 940b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 941e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 9424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 9434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 944931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Determine which BSSID we want to associate to, taking account 945c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // relative strength of 5 and 2.4 GHz BSSIDs 9462451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 9474dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 94897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle for (ScanResult b : current.scanResultCache.values()) { 94997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost5 = 0; 95097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost5 = 0; 95197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost = 0; 95297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost = 0; 953931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if ((b.seen == 0) || (b.BSSID == null) 9540d616ef3bf635dff8722e064c0be842676390ed8vandwalle || ((nowMs - b.seen) > age) 955e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.autoJoinStatus != ScanResult.ENABLED 956e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.numIpConfigFailures > 8) { 9574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 9583a2a3d226881cce8a4e511302231d843b0def303vandwalle } 9594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 960931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Pick first one 9614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (a == null) { 9624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle a = b; 9634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 9644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 9654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 966e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (b.numIpConfigFailures < (a.numIpConfigFailures - 1)) { 967e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // Prefer a BSSID that doesn't have less number of Ip config failures 968e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptRoam: " 969e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + b.BSSID + " rssi=" + b.level + " ipfail=" +b.numIpConfigFailures 970e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + b.frequency 971e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " > " 972e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + a.BSSID + " rssi=" + a.level + " ipfail=" +a.numIpConfigFailures 973e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + a.frequency); 974e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle a = b; 975e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle continue; 976e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 977e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 9782451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply hysteresis: we favor the currentBSSID by giving it a boost 9797806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(b.BSSID)) { 980931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 9810eebae7334d6129f7ca1344e4b20199794994358vandwalle if (b.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5) { 9820eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisLow; 983c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 9840eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 985c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 9864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 9877806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(a.BSSID)) { 9880eebae7334d6129f7ca1344e4b20199794994358vandwalle if (a.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5) { 989931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 9900eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisLow; 991c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 9920eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 993c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 9944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 9952451dbcc4f9641df188326215b204b798eb70c46vandwalle 99697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve 9972451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost the BSSID if it is on 5GHz, above a threshold 9982451dbcc4f9641df188326215b204b798eb70c46vandwalle // But penalize it if it is on 5GHz and below threshold 99997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // 100097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // With he current threshold values, 5GHz network with RSSI above -55 100197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Are given a boost of 30DB which is enough to overcome the current BSSID 100297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases 10039f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // 10049f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // The "current BSSID" Boost must be added to the BSSID's level so as to introduce\ 10059f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // soem amount of hysteresis 1006e67ec726c07410073575473c0f50dc737629f5davandwalle if (b.is5GHz()) { 10079f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.level + bRssiBoost, b.BSSID); 10084dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1009e67ec726c07410073575473c0f50dc737629f5davandwalle if (a.is5GHz()) { 10109f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.level + aRssiBoost, a.BSSID); 10114dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10124dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 10134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 1014c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle String comp = " < "; 1015c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1016c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle comp = " > "; 1017c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 10184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptRoam: " 1019c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost) 102097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency 102197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + comp 1022c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost) 1023c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency); 1024c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 1025c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle 10262451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare the RSSIs after applying the hysteresis boost and the 5GHz 10272451dbcc4f9641df188326215b204b798eb70c46vandwalle // boost if applicable 1028c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1029931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // b is the better BSSID 1030c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle a = b; 10314dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10324dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10333a2a3d226881cce8a4e511302231d843b0def303vandwalle if (a != null) { 10343a2a3d226881cce8a4e511302231d843b0def303vandwalle if (VDBG) { 10357806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle StringBuilder sb = new StringBuilder(); 1036e67ec726c07410073575473c0f50dc737629f5davandwalle sb.append("attemptRoam: " + current.configKey() + 1037e67ec726c07410073575473c0f50dc737629f5davandwalle " Found " + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency); 10387806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null) { 10397806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append(" Current: " + currentBSSID); 10407806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 10417806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append("\n"); 10427806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle logDbg(sb.toString()); 10433a2a3d226881cce8a4e511302231d843b0def303vandwalle } 10444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10453a2a3d226881cce8a4e511302231d843b0def303vandwalle return a; 10464dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10474dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1048931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 10492451dbcc4f9641df188326215b204b798eb70c46vandwalle * getNetworkScore() 10502451dbcc4f9641df188326215b204b798eb70c46vandwalle * 10512451dbcc4f9641df188326215b204b798eb70c46vandwalle * if scorer is present, get the network score of a WifiConfiguration 10522451dbcc4f9641df188326215b204b798eb70c46vandwalle * 10532451dbcc4f9641df188326215b204b798eb70c46vandwalle * Note: this should be merge with setVisibility 10542451dbcc4f9641df188326215b204b798eb70c46vandwalle * 10552451dbcc4f9641df188326215b204b798eb70c46vandwalle * @param config 10562451dbcc4f9641df188326215b204b798eb70c46vandwalle * @return score 10572451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 105881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int getConfigNetworkScore(WifiConfiguration config, int age, boolean isActive) { 10592451dbcc4f9641df188326215b204b798eb70c46vandwalle 10602451dbcc4f9641df188326215b204b798eb70c46vandwalle if (mNetworkScoreCache == null) { 1061e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1062b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1063e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scorer, hence no scores"); 1064e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 10651db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 10661db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 10671db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (config.scanResultCache == null) { 1068e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1069b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1070e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scan cache"); 1071e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 10721db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 10732451dbcc4f9641df188326215b204b798eb70c46vandwalle } 10742451dbcc4f9641df188326215b204b798eb70c46vandwalle 10752451dbcc4f9641df188326215b204b798eb70c46vandwalle // Get current date 10762451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 10772451dbcc4f9641df188326215b204b798eb70c46vandwalle 10781db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle int startScore = -10000; 10791db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle 10802451dbcc4f9641df188326215b204b798eb70c46vandwalle // Run thru all cached scan results 10811db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle for (ScanResult result : config.scanResultCache.values()) { 10822451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((nowMs - result.seen) < age) { 108381c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int sc = mNetworkScoreCache.getNetworkScore(result, isActive); 10841db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (sc > startScore) { 10851db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = sc; 10862451dbcc4f9641df188326215b204b798eb70c46vandwalle } 10872451dbcc4f9641df188326215b204b798eb70c46vandwalle } 10882451dbcc4f9641df188326215b204b798eb70c46vandwalle } 10891db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (startScore == -10000) { 10901db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 10911db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 1092e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1093e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (startScore == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 1094b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1095e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no available score"); 1096e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } else { 1097b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 109881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson + " isActive=" + isActive 1099e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " score = " + Integer.toString(startScore)); 1100e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1101e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1102e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle 11031db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return startScore; 11042451dbcc4f9641df188326215b204b798eb70c46vandwalle } 11052451dbcc4f9641df188326215b204b798eb70c46vandwalle 11062451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 11078639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson * Set whether connections to untrusted connections are allowed. 11088639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson */ 11098639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson void setAllowUntrustedConnections(boolean allow) { 11108639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson boolean changed = mAllowUntrustedConnections != allow; 11118639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson mAllowUntrustedConnections = allow; 11128639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (changed) { 1113005c1ef113192f898499a407dd266393a8d6b076vandwalle // Trigger a scan so as to reattempt autojoin 1114005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiStateMachine.startScanForUntrustedSettingChange(); 11158639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 11168639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 11178639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 11188639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean isOpenNetwork(ScanResult result) { 11198639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson return !result.capabilities.contains("WEP") && 11208639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("PSK") && 11218639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("EAP"); 11228639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 11238639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 11248639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** 1125931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * attemptAutoJoin() function implements the core of the a network switching algorithm 112668fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle * Return false if no acceptable networks were found. 1127931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 112868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean attemptAutoJoin() { 112968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean found = false; 1130c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = false; 11311ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = false; 1132b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkSwitchType = AUTO_JOIN_IDLE; 11334dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 11348242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 11358242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle 11368c9088d11880553458f09377cc60d6eb7e66747bvandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 11378c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1138931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reset the currentConfiguration Key, and set it only if WifiStateMachine and 1139453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 1140453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 1141453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 1142453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1143f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 1144f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1145931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Obtain the subset of recently seen networks 1146833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle List<WifiConfiguration> list = 1147833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.getRecentConfiguredNetworks(mScanResultAutoJoinAge, false); 1148f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 11492f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) logDbg("attemptAutoJoin nothing known=" + 11502f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle mWifiConfigStore.getconfiguredNetworkSize()); 115168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1154931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Find the currently connected network: ask the supplicant directly 115599d385e3b4d34841d6efcfd7cc9bf1d5ae25de14vandwalle String val = mWifiNative.status(true); 1156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String status[] = val.split("\\r?\\n"); 1157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("attemptAutoJoin() status=" + val + " split=" 1159f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(status.length)); 1160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1162b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int supplicantNetId = -1; 1163f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : status) { 1164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (key.regionMatches(0, "id=", 0, 3)) { 1165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int idx = 3; 1166b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId = 0; 1167f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (idx < key.length()) { 1168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle char c = key.charAt(idx); 1169f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1170f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((c >= 0x30) && (c <= 0x39)) { 1171b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId *= 10; 1172b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId += c - 0x30; 1173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle idx++; 1174f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 1176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1177f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 117856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle } else if (key.contains("wpa_state=ASSOCIATING") 117956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle || key.contains("wpa_state=ASSOCIATED") 118056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle || key.contains("wpa_state=FOUR_WAY_HANDSHAKE") 118156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle || key.contains("wpa_state=GROUP_KEY_HANDSHAKE")) { 118256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle if (DBG) { 118356d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle logDbg("attemptAutoJoin: bail out due to sup state " + key); 118456d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle } 118556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // After WifiStateMachine ask the supplicant to associate or reconnect 118656d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // we might still obtain scan results from supplicant 118756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // however the supplicant state in the mWifiInfo and supplicant state tracker 118856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // are updated when we get the supplicant state change message which can be 118956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // processed after the SCAN_RESULT message, so at this point the framework doesn't 119056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // know that supplicant is ASSOCIATING. 119156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // A good fix for this race condition would be for the WifiStateMachine to add 119256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // a new transient state where it expects to get the supplicant message indicating 119356d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // that it started the association process and within which critical operations 119456d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // like autojoin should be deleted. 119556d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle 119656d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // This transient state would remove the need for the roam Wathchdog which 119756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // basically does that. 119856d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle 119956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // At the moment, we just query the supplicant state synchronously with the 120056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // mWifiNative.status() command, which allow us to know that 120156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // supplicant has started association process, even though we didnt yet get the 120256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle // SUPPLICANT_STATE_CHANGE message. 120368fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1204f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1205f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1206ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 12077806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle String conf = ""; 1208b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String last = ""; 12097806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentConfiguration != null) { 1210e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle conf = " current=" + currentConfiguration.configKey(); 1211b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1212b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (lastSelectedConfiguration != null) { 12132f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle last = " last=" + lastSelectedConfiguration; 12147806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 1215ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 1216b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + conf + last 1217b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " ---> suppNetId=" + Integer.toString(supplicantNetId)); 1218ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1219f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1220453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (currentConfiguration != null) { 12212451dbcc4f9641df188326215b204b798eb70c46vandwalle if (supplicantNetId != currentConfiguration.networkId 1222005c1ef113192f898499a407dd266393a8d6b076vandwalle // https://b.corp.google.com/issue?id=16484607 1223005c1ef113192f898499a407dd266393a8d6b076vandwalle // mark this condition as an error only if the mismatched networkId are valid 12242451dbcc4f9641df188326215b204b798eb70c46vandwalle && supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID 12252451dbcc4f9641df188326215b204b798eb70c46vandwalle && currentConfiguration.networkId != WifiConfiguration.INVALID_NETWORK_ID) { 1226453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 1227b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + Integer.toString(supplicantNetId) + " WifiStateMachine=" 1228453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + Integer.toString(currentConfiguration.networkId)); 1229b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle mWifiStateMachine.disconnectCommand(); 123068fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 12318639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } else if (currentConfiguration.ephemeral && (!mAllowUntrustedConnections || 12328639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !mNetworkScoreCache.isScoredNetwork(currentConfiguration.lastSeen()))) { 12338639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // The current connection is untrusted (the framework added it), but we're either 12348639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // no longer allowed to connect to such networks, or the score has been nullified 12358639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // since we connected. Drop the current connection and perform the rest of autojoin. 12368639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network"); 12378639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson mWifiStateMachine.disconnectCommand(); 123868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1239453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else { 1240453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = currentConfiguration.configKey(); 1241453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 12428c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle } else { 12438c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle if (supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID) { 12448c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle // Maybe in the process of associating, skip this attempt 124568fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 12468c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle } 1247453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 1248453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1249b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int currentNetId = -1; 1250b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentConfiguration != null) { 1251931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If we are associated to a configuration, it will 1252b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // be compared thru the compareNetwork function 1253b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle currentNetId = currentConfiguration.networkId; 1254b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 1255b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle 1256931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1257931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Run thru all visible configurations without looking at the one we 1258c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle * are currently associated to 12594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * select Best Network candidate from known WifiConfigurations 1260931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1261f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 1262e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 1263b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle continue; 1264e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 1265e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 126627355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 126727355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) { 1268abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Wait for 5 minutes before reenabling config that have known, 1269abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // repeated connection or DHCP failures 1270abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE 1271abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle || config.disableReason 1272abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle == WifiConfiguration.DISABLED_ASSOCIATION_REJECT 1273abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle || config.disableReason 1274abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle == WifiConfiguration.DISABLED_AUTH_FAILURE) { 1275abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if (config.blackListTimestamp == 0 1276abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle || (config.blackListTimestamp > now)) { 1277abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Sanitize the timestamp 1278abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.blackListTimestamp = now; 1279abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1280abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if ((now - config.blackListTimestamp) > 1281abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle mWifiConfigStore.wifiConfigBlacklistMinTimeMilli) { 1282abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Re-enable the WifiConfiguration 1283abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.status = WifiConfiguration.Status.ENABLED; 1284abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle 1285abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle // Reset the blacklist condition 1286abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.numConnectionFailures = 0; 1287abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.numIpConfigFailures = 0; 1288abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.numAuthFailures = 0; 1289abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 1290abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle 1291abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle config.dirty = true; 1292abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } else { 1293abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle if (VDBG) { 1294abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle long delay = mWifiConfigStore.wifiConfigBlacklistMinTimeMilli 1295abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle - (now - config.blackListTimestamp); 1296abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle logDbg("attemptautoJoin " + config.configKey() 1297abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle + " dont unblacklist yet, waiting for " 1298abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle + delay + " ms"); 1299abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1300abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1301abd1740f753ac14e9dec8fced8d3de5059122c2avandwalle } 1302931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Avoid networks disabled because of AUTH failure altogether 1303ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1304ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin skip candidate due to auto join status " 1305ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + Integer.toString(config.autoJoinStatus) + " key " 1306e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + config.configKey(true) 13078242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " reason " + config.disableReason); 1308ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1309f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1310f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1311f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1312931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to un-blacklist based on elapsed time 131327355a942653264388e909a4276196ee63e57811vandwalle if (config.blackListTimestamp > 0) { 131427355a942653264388e909a4276196ee63e57811vandwalle if (now < config.blackListTimestamp) { 1315931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1316931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * looks like there was a change in the system clock since we black listed, and 1317931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * timestamp is not meaningful anymore, hence lose it. 1318931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * this event should be rare enough so that we still want to lose the black list 13192451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 132027355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 132127355a942653264388e909a4276196ee63e57811vandwalle } else { 13224dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now - config.blackListTimestamp) > loseBlackListHardMilli) { 1323931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable it after 18 hours, i.e. next day 132427355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 13254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) { 1326931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose blacklisting due to bad link 132727355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 8); 132827355a942653264388e909a4276196ee63e57811vandwalle } 132927355a942653264388e909a4276196ee63e57811vandwalle } 133027355a942653264388e909a4276196ee63e57811vandwalle } 133127355a942653264388e909a4276196ee63e57811vandwalle 1332931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to unblacklist based on good visibility 13338c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle if (config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Soft 13348c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle && config.visibility.rssi24 13358c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle < mWifiConfigStore.thresholdUnblacklistThreshold24Soft) { 133627355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 1337c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("attemptAutoJoin do not unblacklist due to low visibility " 13384dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 13394dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) 13404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + config.visibility.rssi24 13414dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.rssi5 13424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 13434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 134427355a942653264388e909a4276196ee63e57811vandwalle } 13458c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle } else if (config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Hard 13468c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle && config.visibility.rssi24 13478c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle < mWifiConfigStore.thresholdUnblacklistThreshold24Hard) { 1348931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If the network is simply temporary disabled, don't allow reconnect until 1349931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // RSSI becomes good enough 135027355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 1); 135127355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 135227355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin good candidate seen, bumped soft -> status=" 135327355a942653264388e909a4276196ee63e57811vandwalle + config.autoJoinStatus 1354b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " " + config.configKey(true) + " rssi=(" 13554dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 13564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 13574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 135827355a942653264388e909a4276196ee63e57811vandwalle } 135927355a942653264388e909a4276196ee63e57811vandwalle } else { 1360c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 3); 136127355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 136227355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin good candidate seen, bumped hard -> status=" 136327355a942653264388e909a4276196ee63e57811vandwalle + config.autoJoinStatus 1364b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " " + config.configKey(true) + " rssi=(" 13654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 13664dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 13674dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 136827355a942653264388e909a4276196ee63e57811vandwalle } 136927355a942653264388e909a4276196ee63e57811vandwalle } 137027355a942653264388e909a4276196ee63e57811vandwalle 137127355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 137227355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 1373931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Network is blacklisted, skip 13744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (DBG) { 13754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptAutoJoin skip blacklisted -> status=" 13764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 1377b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " " + config.configKey(true) + " rssi=(" 13784dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 13794dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 13804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 13814dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 138227355a942653264388e909a4276196ee63e57811vandwalle continue; 138327355a942653264388e909a4276196ee63e57811vandwalle } 1384f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 1385ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 138621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("attemptAutoJoin skip current candidate " 138721bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle + Integer.toString(currentNetId) 1388ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 1389ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1390f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1391f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1392f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 13930eebae7334d6129f7ca1344e4b20199794994358vandwalle boolean isLastSelected = false; 13940eebae7334d6129f7ca1344e4b20199794994358vandwalle if (lastSelectedConfiguration != null && 13950eebae7334d6129f7ca1344e4b20199794994358vandwalle config.configKey().equals(lastSelectedConfiguration)) { 13960eebae7334d6129f7ca1344e4b20199794994358vandwalle isLastSelected = true; 13970eebae7334d6129f7ca1344e4b20199794994358vandwalle } 13980eebae7334d6129f7ca1344e4b20199794994358vandwalle 13990eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.visibility == null) { 14000eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 14010eebae7334d6129f7ca1344e4b20199794994358vandwalle } 14021ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount; 14030eebae7334d6129f7ca1344e4b20199794994358vandwalle if ((config.visibility.rssi5 + boost) 14040eebae7334d6129f7ca1344e4b20199794994358vandwalle < mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI 14050eebae7334d6129f7ca1344e4b20199794994358vandwalle && (config.visibility.rssi24 + boost) 14060eebae7334d6129f7ca1344e4b20199794994358vandwalle < mWifiConfigStore.thresholdInitialAutoJoinAttemptMin24RSSI) { 14070eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 14080eebae7334d6129f7ca1344e4b20199794994358vandwalle logDbg("attemptAutoJoin skip due to low visibility -> status=" 14090eebae7334d6129f7ca1344e4b20199794994358vandwalle + config.autoJoinStatus 14100eebae7334d6129f7ca1344e4b20199794994358vandwalle + " key " + config.configKey(true) + " rssi=" 14110eebae7334d6129f7ca1344e4b20199794994358vandwalle + config.visibility.rssi24 + ", " + config.visibility.rssi5 14120eebae7334d6129f7ca1344e4b20199794994358vandwalle + " num=" + config.visibility.num24 14130eebae7334d6129f7ca1344e4b20199794994358vandwalle + ", " + config.visibility.num5); 14140eebae7334d6129f7ca1344e4b20199794994358vandwalle } 14150eebae7334d6129f7ca1344e4b20199794994358vandwalle 1416c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Don't try to autojoin a network that is too far but 1417c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If that configuration is a user's choice however, try anyway 14180eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!isLastSelected) { 14190eebae7334d6129f7ca1344e4b20199794994358vandwalle config.autoJoinBailedDueToLowRssi = true; 14201ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = true; 14218c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 14220eebae7334d6129f7ca1344e4b20199794994358vandwalle } else { 14230eebae7334d6129f7ca1344e4b20199794994358vandwalle // Next time, try to be a bit more aggressive in auto-joining 14240eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.autoJoinUseAggressiveJoinAttemptThreshold 1425dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle < WifiConfiguration.MAX_INITIAL_AUTO_JOIN_RSSI_BOOST 1426dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle && config.autoJoinBailedDueToLowRssi) { 1427dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle config.autoJoinUseAggressiveJoinAttemptThreshold += 4; 14284dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 14298c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 14300eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1431d30127db46224e45554f8964209221bba8ad41d9vandwalle if (config.numNoInternetAccessReports > 0 1432d30127db46224e45554f8964209221bba8ad41d9vandwalle && !isLastSelected 1433d30127db46224e45554f8964209221bba8ad41d9vandwalle && !config.validatedInternetAccess) { 1434d30127db46224e45554f8964209221bba8ad41d9vandwalle // Avoid autoJoining this network because last time we used it, it didn't 1435d30127db46224e45554f8964209221bba8ad41d9vandwalle // have internet access, and we never manage to validate internet access on this 1436d30127db46224e45554f8964209221bba8ad41d9vandwalle // network configuration 14370eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 1438d30127db46224e45554f8964209221bba8ad41d9vandwalle logDbg("attemptAutoJoin skip candidate due to no InternetAccess " 1439d30127db46224e45554f8964209221bba8ad41d9vandwalle + config.configKey(true) 1440d30127db46224e45554f8964209221bba8ad41d9vandwalle + " num reports " + config.numNoInternetAccessReports); 14419f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 14420eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 14438c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 14448c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1445ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1446e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String cur = ""; 1447e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (candidate != null) { 1448e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle cur = " current candidate " + candidate.configKey(); 1449e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1450e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptAutoJoin trying id=" 1451c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Integer.toString(config.networkId) + " " 1452b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + config.configKey(true) 1453e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " status=" + config.autoJoinStatus 1454e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + cur); 1455ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1456f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1457f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 1458f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1459f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1460f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1461453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 14624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " with " + config.configKey()); 1463f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1464833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(candidate, config); 14652451dbcc4f9641df188326215b204b798eb70c46vandwalle 14662451dbcc4f9641df188326215b204b798eb70c46vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 1467c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 14682451dbcc4f9641df188326215b204b798eb70c46vandwalle // enableNetwork with disableOthers=true WifiManager API 14692451dbcc4f9641df188326215b204b798eb70c46vandwalle // As this is a direct user choice, we strongly prefer this configuration, 14702451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence give +/-100 14712451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((lastSelectedConfiguration != null) 14722451dbcc4f9641df188326215b204b798eb70c46vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 14732451dbcc4f9641df188326215b204b798eb70c46vandwalle // candidate is the last selected configuration, 14742451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 14752451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 14762451dbcc4f9641df188326215b204b798eb70c46vandwalle // by reducing order by -100 14772451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - 100; 14782451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 14792f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers -100 " + candidate.configKey() 14802451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + config.configKey() 14812451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 14822451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 14832451dbcc4f9641df188326215b204b798eb70c46vandwalle } 14842451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if ((lastSelectedConfiguration != null) 14852451dbcc4f9641df188326215b204b798eb70c46vandwalle && config.configKey().equals(lastSelectedConfiguration)) { 14862451dbcc4f9641df188326215b204b798eb70c46vandwalle // config is the last selected configuration, 14872451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 14882451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 14892451dbcc4f9641df188326215b204b798eb70c46vandwalle // by increasing order by +100 14902451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + 100; 14912451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 14922f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers +100 " + config.configKey() 14932451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + candidate.configKey() 14942451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 14952451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 14962451dbcc4f9641df188326215b204b798eb70c46vandwalle } 14972451dbcc4f9641df188326215b204b798eb70c46vandwalle } 14982451dbcc4f9641df188326215b204b798eb70c46vandwalle 1499f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 1500931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Ascending : candidate < config 1501f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1502f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1503f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1504f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1505f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 15062451dbcc4f9641df188326215b204b798eb70c46vandwalle // Now, go thru scan result to try finding a better untrusted network 1507833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if (mNetworkScoreCache != null && mAllowUntrustedConnections) { 1508f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 1509f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 1510f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 1511f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 1512f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 1513f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1514f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1515931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Get current date 15162451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 1517c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int currentScore = -10000; 1518c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // The untrusted network with highest score 1519c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle ScanResult untrustedCandidate = null; 15202451dbcc4f9641df188326215b204b798eb70c46vandwalle // Look for untrusted scored network only if the current candidate is bad 1521c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (isBadCandidate(rssi24, rssi5)) { 1522f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (ScanResult result : scanResultCache.values()) { 1523c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We look only at untrusted networks with a valid SSID 1524c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // A trusted result would have been looked at thru it's Wificonfiguration 15258639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (TextUtils.isEmpty(result.SSID) || !result.untrusted || 15268639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !isOpenNetwork(result)) { 1527c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle continue; 1528c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 15292ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains 15302ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle ("\"" + result.SSID + "\"")) { 15312ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle // SSID had been Forgotten by user, then don't score it 15322ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle continue; 15332ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle } 1534833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if ((nowMs - result.seen) < mScanResultAutoJoinAge) { 1535c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Increment usage count for the network 1536c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics.incrementOrAddUntrusted(result.SSID, 0, 1); 1537c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 153881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean isActiveNetwork = lastUntrustedBSSID != null 153981c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson && result.BSSID.equals(lastUntrustedBSSID); 154081c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int score = mNetworkScoreCache.getNetworkScore(result, isActiveNetwork); 1541c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (score != WifiNetworkScoreCache.INVALID_NETWORK_SCORE 1542c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle && score > currentScore) { 1543c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Highest score: Select this candidate 1544c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle currentScore = score; 1545c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle untrustedCandidate = result; 1546c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (VDBG) { 1547c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("AutoJoinController: found untrusted candidate " 1548c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + result.SSID 1549c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " RSSI=" + result.level 1550c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " freq=" + result.frequency 1551c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " score=" + score); 1552c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1553f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1554f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1555f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1556f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1557c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (untrustedCandidate != null) { 1558c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (lastUntrustedBSSID == null 1559c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle || !untrustedCandidate.SSID.equals(lastUntrustedBSSID)) { 1560c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We found a new candidate that we are going to connect to, then 1561c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // increase its connection count 15628c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle mWifiConnectionStatistics. 15638c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle incrementOrAddUntrusted(untrustedCandidate.SSID, 1, 0); 1564c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Remember which SSID we are connecting to 1565c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle lastUntrustedBSSID = untrustedCandidate.SSID; 1566c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 15678639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 15688639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // At this point, we have an untrusted network candidate. 15698639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // Create the new ephemeral configuration and see if we should switch over 1570833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate = 1571833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.wifiConfigurationFromScanResult(untrustedCandidate); 1572833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.allowedKeyManagement.set(KeyMgmt.NONE); 1573833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.ephemeral = true; 1574c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1575c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1576b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 15771ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle long lastUnwanted = 15781ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle System.currentTimeMillis() 15791ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle - mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp; 15801ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (candidate == null 15811ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && lastSelectedConfiguration == null 15821ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && currentConfiguration == null 15831ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && didBailDueToWeakRssi 15841ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && (mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp == 0 15851ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle || lastUnwanted > (1000 * 60 * 60 * 24 * 7)) 15861ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle ) { 15871ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // We are bailing out of autojoin although we are seeing a weak configuration, and 15881ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we didn't find another valid candidate 15891ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we are not connected 15901ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - without a user network selection choice 15911ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - ConnectivityService has not triggered an unwanted network disconnect 15921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // on this device for a week (hence most likely there is no SIM card or cellular) 15931ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // If all those conditions are met, then boost the RSSI of the weak networks 15941ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // that we are seeing so as we will eventually pick one 15951ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount < 10) 15961ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount += 1; 15971ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } else { 15981ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount > 0) 15991ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount -= 1; 16001ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } 16011ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 1602931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1603931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * If candidate is found, check the state of the connection so as 1604931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * to decide if we should be acting on this candidate and switching over 1605931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1606e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle int networkDelta = compareNetwork(candidate, lastSelectedConfiguration); 1607b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (DBG && candidate != null) { 1608b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String doSwitch = ""; 1609b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String current = ""; 1610b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (networkDelta < 0) { 1611b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle doSwitch = " -> not switching"; 1612b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1613b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (currentConfiguration != null) { 16142f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle current = " with current " + currentConfiguration.configKey(); 1615b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1616b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("attemptAutoJoin networkSwitching candidate " 1617b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + candidate.configKey() 1618b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + current 1619c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + " linked=" + (currentConfiguration != null 1620b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle && currentConfiguration.isLinked(candidate)) 1621b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " : delta=" 1622b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + Integer.toString(networkDelta) + " " 1623b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + doSwitch); 1624b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 16254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1626931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1627931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Ask WifiStateMachine permission to switch : 1628931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * if user is currently streaming voice traffic, 1629931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * then we should not be allowed to switch regardless of the delta 1630931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1631b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) { 1632b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mStaStaSupported) { 1633b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("mStaStaSupported --> error do nothing now "); 1634b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1635b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) { 1636b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING; 1637b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1638b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING; 1639b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1640b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1641b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto connect with netId " 1642b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(candidate.networkId) 1643b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " to " + candidate.configKey()); 1644b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 16452451dbcc4f9641df188326215b204b798eb70c46vandwalle if (didOverride) { 16462451dbcc4f9641df188326215b204b798eb70c46vandwalle candidate.numScorerOverrideAndSwitchedNetwork++; 16472451dbcc4f9641df188326215b204b798eb70c46vandwalle } 1648c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle candidate.numAssociation++; 1649e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoJoinAttempt++; 16509f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 16512f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (candidate.BSSID == null || candidate.BSSID.equals("any")) { 16522f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // First step we selected the configuration we want to connect to 16532f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Second step: Look for the best Scan result for this configuration 16542f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // TODO this algorithm should really be done in one step 16552f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1656833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1657833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, candidate, mScanResultAutoJoinAge, null); 16582f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && currentBSSID != null 16592f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 16602f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Sanity, we were already asociated to that candidate 16612f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle roamCandidate = null; 16622f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 16632f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && roamCandidate.is5GHz()) { 16642f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // If the configuration hasn't a default BSSID selected, and the best 16652f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // candidate is 5GHZ, then select this candidate so as WifiStateMachine and 16662f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // supplicant will pick it first 16672f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle candidate.autoJoinBSSID = roamCandidate.BSSID; 16682f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) { 16692f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("AutoJoinController: lock to 5GHz " 16702f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + candidate.autoJoinBSSID 16712f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " RSSI=" + roamCandidate.level 16722f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " freq=" + roamCandidate.frequency); 16732f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 1674448c9536a302c58a79e271b1721c08b8882f800evandwalle } else { 1675448c9536a302c58a79e271b1721c08b8882f800evandwalle // We couldnt find a roam candidate 1676448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.autoJoinBSSID = "any"; 16779f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 16789f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1679448c9536a302c58a79e271b1721c08b8882f800evandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 1680448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.networkId, networkSwitchType, candidate); 168168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 16824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1683b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 16844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1685b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (networkSwitchType == AUTO_JOIN_IDLE) { 1686e67ec726c07410073575473c0f50dc737629f5davandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1687931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Attempt same WifiConfiguration roaming 1688833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1689833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, currentConfiguration, mScanResultAutoJoinAge, currentBSSID); 1690e67ec726c07410073575473c0f50dc737629f5davandwalle /** 1691e67ec726c07410073575473c0f50dc737629f5davandwalle * TODO: (post L initial release) 1692e67ec726c07410073575473c0f50dc737629f5davandwalle * consider handling linked configurations roaming (i.e. extended Roaming) 1693e67ec726c07410073575473c0f50dc737629f5davandwalle * thru the attemptRoam function which makes use of the RSSI roaming threshold. 1694e67ec726c07410073575473c0f50dc737629f5davandwalle * At the moment, extended roaming is only handled thru the attemptAutoJoin() 1695e67ec726c07410073575473c0f50dc737629f5davandwalle * function which compare configurations. 1696e67ec726c07410073575473c0f50dc737629f5davandwalle * 1697e67ec726c07410073575473c0f50dc737629f5davandwalle * The advantage of making use of attemptRoam function is that this function 1698e67ec726c07410073575473c0f50dc737629f5davandwalle * will looks at all the BSSID of each configurations, instead of only looking 1699e67ec726c07410073575473c0f50dc737629f5davandwalle * at WifiConfiguration.visibility which keeps trackonly of the RSSI/band of the 1700e67ec726c07410073575473c0f50dc737629f5davandwalle * two highest BSSIDs. 1701e67ec726c07410073575473c0f50dc737629f5davandwalle */ 1702e67ec726c07410073575473c0f50dc737629f5davandwalle // Attempt linked WifiConfiguration roaming 1703e67ec726c07410073575473c0f50dc737629f5davandwalle /* if (currentConfiguration != null 1704e67ec726c07410073575473c0f50dc737629f5davandwalle && currentConfiguration.linkedConfigurations != null) { 1705e67ec726c07410073575473c0f50dc737629f5davandwalle for (String key : currentConfiguration.linkedConfigurations.keySet()) { 1706e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration link = mWifiConfigStore.getWifiConfiguration(key); 1707e67ec726c07410073575473c0f50dc737629f5davandwalle if (link != null) { 1708833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle roamCandidate = attemptRoam(roamCandidate, link, mScanResultAutoJoinAge, 1709e67ec726c07410073575473c0f50dc737629f5davandwalle currentBSSID); 1710e67ec726c07410073575473c0f50dc737629f5davandwalle } 1711e67ec726c07410073575473c0f50dc737629f5davandwalle } 1712e67ec726c07410073575473c0f50dc737629f5davandwalle }*/ 1713e67ec726c07410073575473c0f50dc737629f5davandwalle if (roamCandidate != null && currentBSSID != null 1714e67ec726c07410073575473c0f50dc737629f5davandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 1715e67ec726c07410073575473c0f50dc737629f5davandwalle roamCandidate = null; 1716e67ec726c07410073575473c0f50dc737629f5davandwalle } 17172f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && mWifiStateMachine.shouldSwitchNetwork(999)) { 1718b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1719b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto roam with netId " 1720b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(currentConfiguration.networkId) 1721b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " " + currentConfiguration.configKey() + " to BSSID=" 1722b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + roamCandidate.BSSID + " freq=" + roamCandidate.frequency 17231ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle + " RSSI=" + roamCandidate.level); 1724b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1725b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_ROAMING; 1726e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoRoamAttempt++; 1727e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 1728b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM, 1729b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle currentConfiguration.networkId, 1, roamCandidate); 173068fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 1731f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1732f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1733b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType)); 173468fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return found; 1735f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1736f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 1737f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1738