WifiAutoJoinController.java revision 33f9ad2442844df078dde3ae67961e7132a8a48d
1f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/* 262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * Copyright (C) 2014 The Android Open Source Project 3f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 4f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Licensed under the Apache License, Version 2.0 (the "License"); 5f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * you may not use this file except in compliance with the License. 6f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * You may obtain a copy of the License at 7f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 8f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * http://www.apache.org/licenses/LICENSE-2.0 9f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 10f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * Unless required by applicable law or agreed to in writing, software 11f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * distributed under the License is distributed on an "AS IS" BASIS, 12f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * See the License for the specific language governing permissions and 14f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * limitations under the License. 15f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 16f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepackage com.android.server.wifi; 18f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 19f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.content.Context; 20f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkKey; 21f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkScoreManager; 220c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport android.net.WifiKey; 2377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.ScanResult; 2477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.WifiConfiguration; 258639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidsonimport android.net.wifi.WifiConfiguration.KeyMgmt; 2677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.WifiConnectionStatistics; 27f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalleimport android.os.Process; 2877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.provider.Settings; 29c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalleimport android.text.TextUtils; 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log; 31f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 32ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.anqp.ANQPElement; 33ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.anqp.Constants; 34ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.ANQPData; 35ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.AnqpCache; 36ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.Chronograph; 37ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.NetworkDetail; 38ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.PasspointMatch; 39ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.PasspointMatchInfo; 40ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.SupplicantBridge; 41ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport com.android.server.wifi.hotspot2.pps.HomeSP; 42ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 4377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.io.BufferedReader; 4477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.io.IOException; 4577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.io.StringReader; 460c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.ArrayList; 4777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Arrays; 48d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpandeimport java.util.BitSet; 49ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport java.util.Collection; 50f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 5177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Iterator; 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 53ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport java.util.Map; 54f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 56f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 57f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 58f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 59f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 60f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 62f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 63f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 64f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 65f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 66f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 67f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 68f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 69f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 70f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 71f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 72ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean DBG = false; 73ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 74f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 75f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 76c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle public static int mScanResultMaximumAge = 40000; /* milliseconds unit */ 77833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle public static int mScanResultAutoJoinAge = 5000; /* milliseconds unit */ 78c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 79453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 80f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande private final HashMap<String, ScanDetail> scanResultCache = new HashMap<>(); 82f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 83c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle private WifiConnectionStatistics mWifiConnectionStatistics; 84c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 858639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** Whether to allow connections to untrusted networks. */ 868639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean mAllowUntrustedConnections = false; 878639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 88c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /* For debug purpose only: if the scored override a score */ 89c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle boolean didOverride = false; 90c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 91931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose the non-auth failure blacklisting after 8 hours 924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListHardMilli = 1000 * 60 * 60 * 8; 93931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose some temporary blacklisting after 30 minutes 944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListSoftMilli = 1000 * 60 * 30; 9527355a942653264388e909a4276196ee63e57811vandwalle 9616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson /** @see android.provider.Settings.Global#WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS */ 9716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private static final long DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS = 1000 * 60; // 1 minute 9816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 99b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_IDLE = 0; 100b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_ROAMING = 1; 101b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_EXTENDED_ROAMING = 2; 102b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3; 103b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 10497b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle public static final int HIGH_THRESHOLD_MODIFIER = 5; 10597b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle 1061ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // Below are AutoJoin wide parameters indicating if we should be aggressive before joining 1071ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // weak network. Note that we cannot join weak network that are going to be marked as unanted by 1081ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // ConnectivityService because this will trigger link flapping. 1091ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 1101ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * There was a non-blacklisted configuration that we bailed from because of a weak signal 1111ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 1121ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle boolean didBailDueToWeakRssi = false; 1131ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 1141ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * number of time we consecutively bailed out of an eligible network because its signal 1151ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * was too weak 1161ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 1171ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int weakRssiBailCount = 0; 1181ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 120c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle WifiConnectionStatistics st, WifiNative n) { 121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 124f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 125f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 126c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics = st; 12721bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle scoreManager = 12821bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 131f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 132f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 133f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 138f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 139f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 140f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 141f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 142f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 143ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 144ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (verbose > 0 ) { 145abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = true; 146ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 147ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 148abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = false; 149ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 150ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 151ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 152ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 153931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 154931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Flush out scan results older than mScanResultMaximumAge 155ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * 156931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 159931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle delay = mScanResultMaximumAge; // Something sane 160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 161b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long milli = System.currentTimeMillis(); 162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 163f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 166f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 16725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande Iterator<HashMap.Entry<String,ScanDetail>> iter = scanResultCache.entrySet().iterator(); 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 16925ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande HashMap.Entry<String,ScanDetail> entry = iter.next(); 17025ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanDetail scanDetail = entry.getValue(); 17125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if ((scanDetail.getSeen() + delay) < milli) { 172f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 174f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 177ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 178d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande void averageRssiAndRemoveFromCache(ScanResult result) { 179d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // Fetch the previous instance for this result 18025ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanDetail sd = scanResultCache.get(result.BSSID); 18125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (sd != null) { 18225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult sr = sd.getScanResult(); 183d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 184d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande && result.level == 0 185d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande && sr.level < -20) { 186d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // A 'zero' RSSI reading is most likely a chip problem which returns 187d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // an unknown RSSI, hence ignore it 188d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande result.level = sr.level; 189ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 190ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 191d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // If there was a previous cache result for this BSSID, average the RSSI values 192d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge); 193ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 194d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // Remove the previous Scan Result - this is not necessary 195d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande scanResultCache.remove(result.BSSID); 196d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } else if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 && result.level == 0) { 197d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // A 'zero' RSSI reading is most likely a chip problem which returns 198d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // an unknown RSSI, hence initialize it to a sane value 199d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande result.level = mWifiConfigStore.scanResultRssiLevelPatchUp; 200ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 201ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 202ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 203d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande void addToUnscoredNetworks(ScanResult result, List<NetworkKey> unknownScanResults) { 204d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande WifiKey wkey; 205d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande // Quoted SSIDs are the only one valid at this stage 206d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande try { 207d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 208d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } catch (IllegalArgumentException e) { 209d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID + 210d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande "] ->skipping this network"); 211d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande wkey = null; 212d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 213d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (wkey != null) { 214d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande NetworkKey nkey = new NetworkKey(wkey); 215d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande //if we don't know this scan result then request a score from the scorer 216d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande unknownScanResults.add(nkey); 217ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 218d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (VDBG) { 219d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande String cap = ""; 220d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (result.capabilities != null) 221d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande cap = result.capabilities; 222d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande logDbg(result.SSID + " " + result.BSSID + " rssi=" 223d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande + result.level + " cap " + cap + " is not scored"); 224ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 225ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 226ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 22777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int addToScanCache(List<ScanDetail> scanList) { 228be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown = 0; // Record number of scan results we knew about 229be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiConfiguration associatedConfig = null; 2307b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle boolean didAssociate = false; 2318242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 232f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 2330c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 2340c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 235d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande for(ScanDetail scanDetail : scanList) { 23677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ScanResult result = scanDetail.getScanResult(); 2371fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (result.SSID == null) continue; 238c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 239c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Make sure we record the last time we saw this result 24025ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande scanDetail.setSeen(); 241f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 242d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande averageRssiAndRemoveFromCache(result); 243e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 244e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 245d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande addToUnscoredNetworks(result, unknownScanResults); 2460c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 247e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 2487b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 2497b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 2507b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 251e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 252e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 2537b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is scored : " + score); 2540c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 255f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 256f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 257e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // scanResultCache.put(result.BSSID, new ScanResult(result)); 25825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande scanResultCache.put(result.BSSID, scanDetail); 259be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // Add this BSSID to the scanResultCache of a Saved WifiConfiguration 260d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande didAssociate = mWifiConfigStore.updateSavedNetworkHistory(scanDetail); 261f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 262be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // If not successful, try to associate this BSSID to an existing Saved WifiConfiguration 2637b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (!didAssociate) { 264be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // We couldn't associate the scan result to a Saved WifiConfiguration 265c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Hence it is untrusted 266c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.untrusted = true; 26725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande associatedConfig = mWifiConfigStore.associateWithConfiguration(scanDetail); 2681fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (associatedConfig != null && associatedConfig.SSID != null) { 269f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 270f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("addToScanCache save associated config " 2718242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + associatedConfig.SSID + " with " + result.SSID 2728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " status " + associatedConfig.autoJoinStatus 2738242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " reason " + associatedConfig.disableReason 2748242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " tsp " + associatedConfig.blackListTimestamp 2758242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " was " + (now - associatedConfig.blackListTimestamp)); 276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 277be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle mWifiStateMachine.sendMessage( 278be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiStateMachine.CMD_AUTO_SAVE_NETWORK, associatedConfig); 2797b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = true; 280f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2810d616ef3bf635dff8722e064c0be842676390ed8vandwalle } else { 2820d616ef3bf635dff8722e064c0be842676390ed8vandwalle // If the scan result has been blacklisted fir 18 hours -> unblacklist 2830d616ef3bf635dff8722e064c0be842676390ed8vandwalle if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { 2840d616ef3bf635dff8722e064c0be842676390ed8vandwalle result.setAutoJoinStatus(ScanResult.ENABLED); 2850d616ef3bf635dff8722e064c0be842676390ed8vandwalle } 286f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2877b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (didAssociate) { 288be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown++; 289a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate ++; 290a0708b09ad17b086c008ab100aec7143d7613c80vandwalle } else { 291a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate = 0; 292be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 293f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2940c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 2950c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 2960c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 2970c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 298931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Kick the score manager, we will get updated scores asynchronously 2990c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 3000c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 301be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 302f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 303f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 304f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 3050888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle logDbg(message, false); 306ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 307ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 308ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 309ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 31033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande Log.d(TAG, message + " stack:" 311ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 312ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 313ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 314ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 315ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 31633f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande Log.d(TAG, message); 317ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 318f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 319f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 320931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Called directly from WifiStateMachine 321be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int newSupplicantResults(boolean doAutoJoin) { 322be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown; 32377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist List<ScanDetail> scanList = mWifiStateMachine.getScanResultsListNoCopyUnsync(); 324be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown = addToScanCache(scanList); 325f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 326be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle if (DBG) { 327be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) 3282f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " known=" + numScanResultsKnown + " " 3299f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle + doAutoJoin); 330be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 3317806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (doAutoJoin) { 3327806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle attemptAutoJoin(); 3337806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 334005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 335be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 336f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 337f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 338f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 339931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 340931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Not used at the moment 341f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 342f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 343f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 344f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 345f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 346f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 34777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist List<ScanDetail> scanList = null;//mWifiScanner.syncGetScanResultsList(); 348f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 349f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 350f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 351f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 352f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 353005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 354f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 355f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 356931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 357931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * network link quality changed, called directly from WifiTrafficPoller, 358931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * or by listening to Link Quality intent 359931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 360f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 361f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 362f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 363f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 364931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 365f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 366f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 367f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 368f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 369b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * Negatve return values from this functions are meaningless per se, just trying to 370b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * keep them distinct for debug purpose (i.e. -1, -2 etc...) 371931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 372e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle private int compareNetwork(WifiConfiguration candidate, 373e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String lastSelectedConfiguration) { 374b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (candidate == null) 375b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -3; 376b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 377f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 378b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentNetwork == null) { 379c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Return any absurdly high score, if we are not connected there is no current 380c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // network to... 381b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return 1000; 382b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 383f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 384f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 385b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -2; 386f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 387f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 388b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (DBG) { 389e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("compareNetwork will compare " + candidate.configKey() 390e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " with current " + currentNetwork.configKey()); 391b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 392833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 393e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 394e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 395e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 396e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // enableNetwork with disableOthers=true WifiManager API 397e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // As this is a direct user choice, we strongly prefer this configuration, 398e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // hence give +/-100 399e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if ((lastSelectedConfiguration != null) 400e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && currentNetwork.configKey().equals(lastSelectedConfiguration)) { 401e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // currentNetwork is the last selected configuration, 402e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 403e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 404e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by reducing order by -100 405e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order - 100; 406e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 407e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers -100 " + currentNetwork.configKey() 408e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + candidate.configKey() 409e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 410e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 411e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 412e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } else if ((lastSelectedConfiguration != null) 413e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 414e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // candidate is the last selected configuration, 415e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 416e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 417e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by increasing order by +100 418e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order + 100; 419e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 420e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers +100 " + candidate.configKey() 421e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + currentNetwork.configKey() 422e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 423e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 424e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 425e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 426e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 427ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle return order; 428f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 429f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 430ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 431ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 432ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 433ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 434ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 435ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 43662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 437ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 438ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 439ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param connect : if the update includes a connect 440931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 44162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 442f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 443f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 444c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + " no selected configuration!"); 445f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 447f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 448e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 449c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + 450c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle " no SSID in selected configuration!"); 451e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 452e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 453e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 45462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 455931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable autojoin for this network, 45662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 45727355a942653264388e909a4276196ee63e57811vandwalle selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 45862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 459e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle selected.dirty = true; 46062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 461f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 462992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG && userTriggered) { 463f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 464ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 465f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 466992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(selected.connectChoices.size()) 467992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 468f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 469ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 470992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(netId) 471992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 472f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 473f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 474f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 475ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 476ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 4772451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice = 0; 478c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int size = 0; 4799f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 4809f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // Reset the triggered disabled count, because user wanted to connect to this 4819f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // configuration, and we were not. 4829f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableLowRSSI = 0; 4839f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableBadRSSI = 0; 4849f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableNotHighRSSI = 0; 4859f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredJoinAttempts++; 4869f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 48762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 48862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 489c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (networks != null) size = networks.size(); 490c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory found " + size + " networks"); 49162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 49262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 493992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG) { 494992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle logDbg("updateConfigurationHistory got " + config.SSID + " nid=" 495992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(config.networkId)); 496992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 497f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 49862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 499ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 50062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 50162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 502f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5032451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare RSSI values so as to evaluate the strength of the user preference 5042451dbcc4f9641df188326215b204b798eb70c46vandwalle int order = compareWifiConfigurationsRSSI(config, selected, null); 5052451dbcc4f9641df188326215b204b798eb70c46vandwalle 5062451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order < -30) { 5072451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is worse than the visible configuration 5082451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a strong choice so as autojoin cannot override this 5092451dbcc4f9641df188326215b204b798eb70c46vandwalle // for instance, the user has select a network 5102451dbcc4f9641df188326215b204b798eb70c46vandwalle // with 1 bar over a network with 3 bars... 5112451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 60; 5122451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -20) { 5132451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 50; 5142451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -10) { 5152451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 40; 5162f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else if (order < 20) { 5172451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is about same or has a slightly better RSSI 5182451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a weaker choice, here a difference of at least +/-30 in 5192451dbcc4f9641df188326215b204b798eb70c46vandwalle // RSSI comparison triggered by autoJoin will override the choice 5202451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 30; 5212f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else { 5222451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is better than the visible configuration 5232451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence we do not know if the user prefers this configuration strongly 5242451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; 52562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 526f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 527931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // The selected configuration was preferred over a recently seen config 528931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // hence remember the user's choice: 529931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // add the recently seen config to the selected's connectChoices array 530ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 531ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (selected.connectChoices == null) { 532ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle selected.connectChoices = new HashMap<String, Integer>(); 533ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 534ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 535ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory add a choice " + selected.configKey(true) 5360888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle + " over " + config.configKey(true) 5372451dbcc4f9641df188326215b204b798eb70c46vandwalle + " choice " + Integer.toString(choice)); 538cf5b8eb8a08c45bd4a82f1f4bb789c8a1b08744fvandwalle 5392451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer currentChoice = selected.connectChoices.get(config.configKey(true)); 5402f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (currentChoice != null) { 5412f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // User has made this choice multiple time in a row, so bump up a lot 54233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande choice += currentChoice; 5432451dbcc4f9641df188326215b204b798eb70c46vandwalle } 5442f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Add the visible config to the selected's connect choice list 5452f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle selected.connectChoices.put(config.configKey(true), choice); 546f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 54762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 548ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 549ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 55062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 551ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 552931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected from the recently seen config's connectChoice list 55362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 5540888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 5550888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (selected.linkedConfigurations != null) { 556931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected's linked configuration from the 557931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // recently seen config's connectChoice list 5580888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle for (String key : selected.linkedConfigurations.keySet()) { 5590888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle config.connectChoices.remove(key); 5600888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 5610888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 56262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 563ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 564ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 5652451dbcc4f9641df188326215b204b798eb70c46vandwalle // We haven't found the configuration that the user just selected in our 5662451dbcc4f9641df188326215b204b798eb70c46vandwalle // scan cache. 5672451dbcc4f9641df188326215b204b798eb70c46vandwalle // In that case we will need a new scan before attempting to connect to this 5682451dbcc4f9641df188326215b204b798eb70c46vandwalle // configuration anyhow and thus we can process the scan results then. 569ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 570ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + selected.configKey()); 57162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 572f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 57362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 57462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 575ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 57662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 57762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 578f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 579f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 580992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle 581931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // TODO: write only if something changed 582992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (userTriggered || connect) { 583005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 584992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 585f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 586f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5872451dbcc4f9641df188326215b204b798eb70c46vandwalle int getConnectChoice(WifiConfiguration source, WifiConfiguration target) { 5882451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer choice = null; 5892451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source == null || target == null) { 5902451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 591f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 592f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5932451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source.connectChoices != null 5942451dbcc4f9641df188326215b204b798eb70c46vandwalle && source.connectChoices.containsKey(target.configKey(true))) { 5952451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = source.connectChoices.get(target.configKey(true)); 5962451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (source.linkedConfigurations != null) { 597f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 598f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 599f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 600f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 6012451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = config.connectChoices.get(target.configKey(true)); 602f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 603f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 604f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 6052451dbcc4f9641df188326215b204b798eb70c46vandwalle } 6062451dbcc4f9641df188326215b204b798eb70c46vandwalle 6072451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice == null) { 60833f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande // We didn't find the connect choice; fallback to some default choices 60933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande int sourceScore = getSecurityScore(source); 61033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande int targetScore = getSecurityScore(target); 61133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande choice = targetScore - sourceScore; 61233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande } 61333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande 61433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (choice < 0) { 61533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande choice = 20; // Compatibility with older files 6162451dbcc4f9641df188326215b204b798eb70c46vandwalle } 61733f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande 61833f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande return choice; 6192451dbcc4f9641df188326215b204b798eb70c46vandwalle } 6202451dbcc4f9641df188326215b204b798eb70c46vandwalle 62133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande int compareWifiConfigurationsFromVisibility(WifiConfiguration.Visibility a, int aRssiBoost, 62233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande String dbgA, WifiConfiguration.Visibility b, int bRssiBoost, String dbgB) { 6232451dbcc4f9641df188326215b204b798eb70c46vandwalle 624815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int aRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) 625815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int bRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) 626815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 627815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int aScore = 0; 628815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int bScore = 0; 629815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 630815788ba7838fc54310baed3deb9b95548e0ce69vandwalle boolean aPrefers5GHz = false; 631815788ba7838fc54310baed3deb9b95548e0ce69vandwalle boolean bPrefers5GHz = false; 6324dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 6332451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 634815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * Calculate a boost to apply to RSSI value of configuration we want to join on 5GHz: 635815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * Boost RSSI value of 5GHz bands iff the base value is better than threshold, 636815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * penalize the RSSI value of 5GHz band iff the base value is lower than threshold 6372451dbcc4f9641df188326215b204b798eb70c46vandwalle * This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas 6382451dbcc4f9641df188326215b204b798eb70c46vandwalle * we prefer 2.4GHz otherwise. 6392451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 64033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aRssiBoost5 = rssiBoostFrom5GHzRssi(a.rssi5, dbgA + "->"); 64133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bRssiBoost5 = rssiBoostFrom5GHzRssi(b.rssi5, dbgB + "->"); 6422451dbcc4f9641df188326215b204b798eb70c46vandwalle 643815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for a 64433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (a.rssi5 + aRssiBoost5 > a.rssi24) { 6452451dbcc4f9641df188326215b204b798eb70c46vandwalle // Prefer a's 5GHz 646815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aPrefers5GHz = true; 647815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 648815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 649815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for b 65033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (b.rssi5 + bRssiBoost5 > b.rssi24) { 651815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Prefer b's 5GHz 652815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bPrefers5GHz = true; 653815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 654815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 655815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (aPrefers5GHz) { 656815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (bPrefers5GHz) { 657815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either 658815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // one, but directly compare the RSSI values, this improves stability, 659815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // since the 5GHz RSSI boost can introduce large fluctuations 66033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aScore = a.rssi5 + aRssiBoost; 661815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 662815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only a is on 5GHz, then apply the 5GHz preference boost to a 66333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aScore = a.rssi5 + aRssiBoost + aRssiBoost5; 664815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 6652451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 66633f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande aScore = a.rssi24 + aRssiBoost; 667f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 6682451dbcc4f9641df188326215b204b798eb70c46vandwalle 669815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (bPrefers5GHz) { 670815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (aPrefers5GHz) { 671815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either 672815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // one, but directly compare the RSSI values, this improves stability, 673815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // since the 5GHz RSSI boost can introduce large fluctuations 67433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bScore = b.rssi5 + bRssiBoost; 675815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 676815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only b is on 5GHz, then apply the 5GHz preference boost to b 67733f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bScore = b.rssi5 + bRssiBoost + bRssiBoost5; 678815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 679815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 68033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande bScore = b.rssi24 + bRssiBoost; 681815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 68233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande 683815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (VDBG) { 68433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande logDbg(" " + dbgA + " is5=" + aPrefers5GHz + " score=" + aScore 68533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande + " " + dbgB + " is5=" + bPrefers5GHz + " score=" + bScore); 686815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 687f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 688f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle // Debug only, record RSSI comparison parameters 68933f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (a != null) { 69033f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.score = aScore; 69133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.currentNetworkBoost = aRssiBoost; 69233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.bandPreferenceBoost = aRssiBoost5; 693f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 69433f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande if (b != null) { 69533f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.score = bScore; 69633f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.currentNetworkBoost = bRssiBoost; 69733f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.bandPreferenceBoost = bRssiBoost5; 698f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 699f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 700815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Compare a and b 701815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If a score is higher then a > b and the order is descending (negative) 702815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If b score is higher then a < b and the order is ascending (positive) 703815788ba7838fc54310baed3deb9b95548e0ce69vandwalle return bScore - aScore; 704f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 705f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 7062451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50] 7072451dbcc4f9641df188326215b204b798eb70c46vandwalle // The result represents "approximately" an RSSI difference measured in dBM 7082451dbcc4f9641df188326215b204b798eb70c46vandwalle // Adjusted with various parameters: 7092451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) current network gets a +15 boost 7102451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) 5GHz signal, if they are strong enough, get a +15 or +25 boost, representing the 7112451dbcc4f9641df188326215b204b798eb70c46vandwalle // fact that at short range we prefer 5GHz band as it is cleaner of interference and 7122451dbcc4f9641df188326215b204b798eb70c46vandwalle // provides for wider channels 7132451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b, 7142451dbcc4f9641df188326215b204b798eb70c46vandwalle String currentConfiguration) { 715f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 7162451dbcc4f9641df188326215b204b798eb70c46vandwalle 7172451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost used so as to favor current config 7182451dbcc4f9641df188326215b204b798eb70c46vandwalle int aRssiBoost = 0; 7192451dbcc4f9641df188326215b204b798eb70c46vandwalle int bRssiBoost = 0; 7202451dbcc4f9641df188326215b204b798eb70c46vandwalle 7212451dbcc4f9641df188326215b204b798eb70c46vandwalle // Retrieve the visibility 722f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 723f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 724f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 7252451dbcc4f9641df188326215b204b798eb70c46vandwalle // Error visibility wasn't set 726b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations NULL band status!"); 727f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 728f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7292451dbcc4f9641df188326215b204b798eb70c46vandwalle 7302451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis, boost RSSI of current configuration 7312451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != currentConfiguration) { 7322451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(currentConfiguration)) { 73393a1fddee50a244d31036cddae6b7db6630fd93dvandwalle aRssiBoost = mWifiConfigStore.currentNetworkBoost; 7342451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(currentConfiguration)) { 73593a1fddee50a244d31036cddae6b7db6630fd93dvandwalle bRssiBoost = mWifiConfigStore.currentNetworkBoost; 7362451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7372451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7382451dbcc4f9641df188326215b204b798eb70c46vandwalle 7392451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 740b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI: " + a.configKey() 741f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " rssi=" + Integer.toString(astatus.rssi24) 742c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + "," + Integer.toString(astatus.rssi5) 7432451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(aRssiBoost) 744f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " " + b.configKey() + " rssi=" 745c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi24) + "," 746c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi5) 7472451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(bRssiBoost) 7482451dbcc4f9641df188326215b204b798eb70c46vandwalle ); 749f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7502451dbcc4f9641df188326215b204b798eb70c46vandwalle 75133f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande order = compareWifiConfigurationsFromVisibility( 75233f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande a.visibility, aRssiBoost, a.configKey(), 75333f9ad2442844df078dde3ae67961e7132a8a48dVinit Deshpande b.visibility, bRssiBoost, b.configKey()); 7542451dbcc4f9641df188326215b204b798eb70c46vandwalle 7552451dbcc4f9641df188326215b204b798eb70c46vandwalle // Normalize the order to [-50, +50] 7562451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 50) order = 50; 7572451dbcc4f9641df188326215b204b798eb70c46vandwalle else if (order < -50) order = -50; 7582451dbcc4f9641df188326215b204b798eb70c46vandwalle 7592451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 7602451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 7612451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 0) { 7622451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; // Ascending 7632451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < 0) { 7642451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; // Descending 7652451dbcc4f9641df188326215b204b798eb70c46vandwalle } 766b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI " + a.configKey() 7672451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 7682451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 7692451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 7702451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 7712451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 7722451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 7732451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 7742451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 7752451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 7762451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + order); 7772451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7782451dbcc4f9641df188326215b204b798eb70c46vandwalle 779f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 780f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 781f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 782833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /** 783833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * b/18490330 only use scorer for untrusted networks 784833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * 7852451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsWithScorer(WifiConfiguration a, WifiConfiguration b) { 7862451dbcc4f9641df188326215b204b798eb70c46vandwalle 78781c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean aIsActive = false; 78881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean bIsActive = false; 7892451dbcc4f9641df188326215b204b798eb70c46vandwalle 7902451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis : boost RSSI of current configuration before 7912451dbcc4f9641df188326215b204b798eb70c46vandwalle // looking up the score 7922451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != mCurrentConfigurationKey) { 7932451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(mCurrentConfigurationKey)) { 79481c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson aIsActive = true; 7952451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(mCurrentConfigurationKey)) { 79681c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson bIsActive = true; 7972451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7982451dbcc4f9641df188326215b204b798eb70c46vandwalle } 799833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreA = getConfigNetworkScore(a, mScanResultAutoJoinAge, aIsActive); 800833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreB = getConfigNetworkScore(b, mScanResultAutoJoinAge, bIsActive); 8012451dbcc4f9641df188326215b204b798eb70c46vandwalle 8022451dbcc4f9641df188326215b204b798eb70c46vandwalle // Both configurations need to have a score for the scorer to be used 8032451dbcc4f9641df188326215b204b798eb70c46vandwalle // ...and the scores need to be different:-) 8042451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA == WifiNetworkScoreCache.INVALID_NETWORK_SCORE 8052451dbcc4f9641df188326215b204b798eb70c46vandwalle || scoreB == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 806e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 807b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer no-scores: " 808e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + a.configKey() 809e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " " 810e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + b.configKey()); 811e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 8122451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 8132451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8142451dbcc4f9641df188326215b204b798eb70c46vandwalle 8152451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 8162451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 8172451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA < scoreB) { 8182451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; 8192451dbcc4f9641df188326215b204b798eb70c46vandwalle } if (scoreA > scoreB) { 8202451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; 8212451dbcc4f9641df188326215b204b798eb70c46vandwalle } 822b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer " + a.configKey() 8232451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 8242451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 8252451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 8262451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 827e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreA 8282451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 8292451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 8302451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 8312451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 8322451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 833e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreB 8342451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + Integer.toString(scoreB - scoreA)); 8352451dbcc4f9641df188326215b204b798eb70c46vandwalle } 836c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 8372451dbcc4f9641df188326215b204b798eb70c46vandwalle // If scoreA > scoreB, the comparison is descending hence the return value is negative 8382451dbcc4f9641df188326215b204b798eb70c46vandwalle return scoreB - scoreA; 8392451dbcc4f9641df188326215b204b798eb70c46vandwalle } 840833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 8412451dbcc4f9641df188326215b204b798eb70c46vandwalle 842d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande int getSecurityScore(WifiConfiguration config) { 843d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 844d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (TextUtils.isEmpty(config.SSID) == false) { 845d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) 846d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande || config.allowedKeyManagement.get(KeyMgmt.WPA_PSK) 847d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande || config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 848d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* enterprise or PSK networks get highest score */ 849d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 100; 850d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } else if (config.allowedKeyManagement.get(KeyMgmt.NONE)) { 851d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* open networks have lowest score */ 852d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 33; 853d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 854d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } else if (TextUtils.isEmpty(config.FQDN) == false) { 855d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* passpoint networks have medium preference */ 856d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 66; 857d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 858d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 859d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande /* bad network */ 860d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande return 0; 861d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 862d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 863f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 864f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 865f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 866f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 867453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 868453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 869453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 8702451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((a.linkedConfigurations.get(b.configKey(true)) != null) 8712451dbcc4f9641df188326215b204b798eb70c46vandwalle && (b.linkedConfigurations.get(a.configKey(true)) != null)) { 872f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 873f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 874f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 875f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 876f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 877f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 878b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + b.configKey() 879453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 880f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 881931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return 1; // b is of higher priority - ascending 882f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 883f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 884f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 885b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + a.configKey() 886453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 887f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 888931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return -1; // a is of higher priority - descending 889f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 890f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8912451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply RSSI, in the range [-5, +5] 8922451dbcc4f9641df188326215b204b798eb70c46vandwalle // after band adjustment, +n difference roughly corresponds to +10xn dBm 8932451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + compareWifiConfigurationsRSSI(a, b, mCurrentConfigurationKey); 894f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8952451dbcc4f9641df188326215b204b798eb70c46vandwalle // If the configurations are not linked, compare by user's choice, only a 8962451dbcc4f9641df188326215b204b798eb70c46vandwalle // very high RSSI difference can then override the choice 8972451dbcc4f9641df188326215b204b798eb70c46vandwalle if (!linked) { 8982451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice; 899f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9002451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(a, b); 9012451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 902931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 9032451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - choice; 904f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 905b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + a.configKey() 906453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 907b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " due to user choice of " + choice 908b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order -> " + Integer.toString(order)); 909f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 910f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility != null) { 911f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceBoost = choice; 912f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceConfig = b.configKey(); 913f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 9142451dbcc4f9641df188326215b204b798eb70c46vandwalle } 9152451dbcc4f9641df188326215b204b798eb70c46vandwalle 9162451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(b, a); 9172451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 918931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 9192451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + choice; 9204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 921b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + b.configKey() + " over " 922b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + a.configKey() + " due to user choice of " + choice 923b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order ->" + Integer.toString(order)); 924f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 925f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (b.visibility != null) { 926f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceBoost = choice; 927f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceConfig = a.configKey(); 928f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 929f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 930f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 931ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 932f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 933931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // We don't know anything - pick the last seen i.e. K behavior 934931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // we should do this only for recently picked configurations 935f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 936931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 9372451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 938b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers -1 " + a.configKey() + " over " 939453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 940f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 941f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 942f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 943f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 944931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 9452451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 946b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers +1 " + b.configKey() + " over " 947453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 948f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 9492451dbcc4f9641df188326215b204b798eb70c46vandwalle order = 1; 950f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 951f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 952f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 953f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 954931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if (order > 0) { 955f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 956931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } else if (order < 0) { 957f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 958931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } 959f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9602451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 961b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("compareWifiConfigurations: " + a.configKey() + sorder 962453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 963f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 964f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 965f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 966f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 967f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 968c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle boolean isBadCandidate(int rssi5, int rssi24) { 969c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle return (rssi5 < -80 && rssi24 < -90); 970c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 971c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 972833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /* 973c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int compareWifiConfigurationsTop(WifiConfiguration a, WifiConfiguration b) { 974c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int scorerOrder = compareWifiConfigurationsWithScorer(a, b); 975c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int order = compareWifiConfigurations(a, b); 976c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 977c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder * order < 0) { 978b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (VDBG) { 979b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" -> compareWifiConfigurationsTop: " + 980b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle "scorer override " + scorerOrder + " " + order); 981b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 982c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // For debugging purpose, remember that an override happened 983c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // during that autojoin Attempt 984c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = true; 985c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle a.numScorerOverride++; 986c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle b.numScorerOverride++; 987c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 988c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 989c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder != 0) { 990c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If the scorer came up with a result then use the scorer's result, else use 991c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // the order provided by the base comparison function 992c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle order = scorerOrder; 993c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 994c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle return order; 995c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 996833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 997c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 9989f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle public int rssiBoostFrom5GHzRssi(int rssi, String dbg) { 9990eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!mWifiConfigStore.enable5GHzPreference) { 10000eebae7334d6129f7ca1344e4b20199794994358vandwalle return 0; 10010eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1002e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 100377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist > mWifiConfigStore.bandPreferenceBoostThreshold5.get()) { 1004e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 2 dB for each point 1005e67ec726c07410073575473c0f50dc737629f5davandwalle // Start boosting at -65 1006e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 20 if above -55 1007e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 40 if abore -45 10080eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferenceBoostFactor5 100977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist *(rssi - mWifiConfigStore.bandPreferenceBoostThreshold5.get()); 1010e67ec726c07410073575473c0f50dc737629f5davandwalle if (boost > 50) { 1011815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // 50 dB boost allows jumping from 2.4 to 5GHz 1012e67ec726c07410073575473c0f50dc737629f5davandwalle // consistently 1013e67ec726c07410073575473c0f50dc737629f5davandwalle boost = 50; 1014e67ec726c07410073575473c0f50dc737629f5davandwalle } 10159f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle if (VDBG && dbg != null) { 1016f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle logDbg(" " + dbg + ": rssi5 " + rssi + " 5GHz-boost " + boost); 10179f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1018e67ec726c07410073575473c0f50dc737629f5davandwalle return boost; 1019e67ec726c07410073575473c0f50dc737629f5davandwalle } 1020e67ec726c07410073575473c0f50dc737629f5davandwalle 1021e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 102277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist < mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 10230eebae7334d6129f7ca1344e4b20199794994358vandwalle // penalize if < -75 10240eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferencePenaltyFactor5 102577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist *(rssi - mWifiConfigStore.bandPreferencePenaltyThreshold5.get()); 10260eebae7334d6129f7ca1344e4b20199794994358vandwalle return boost; 1027e67ec726c07410073575473c0f50dc737629f5davandwalle } 1028e67ec726c07410073575473c0f50dc737629f5davandwalle return 0; 1029e67ec726c07410073575473c0f50dc737629f5davandwalle } 1030c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /** 1031e67ec726c07410073575473c0f50dc737629f5davandwalle * attemptRoam() function implements the core of the same SSID switching algorithm 1032e67ec726c07410073575473c0f50dc737629f5davandwalle * 1033e67ec726c07410073575473c0f50dc737629f5davandwalle * Run thru all recent scan result of a WifiConfiguration and select the 1034e67ec726c07410073575473c0f50dc737629f5davandwalle * best one. 1035c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle */ 1036e67ec726c07410073575473c0f50dc737629f5davandwalle public ScanResult attemptRoam(ScanResult a, 1037e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration current, int age, String currentBSSID) { 1038b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current == null) { 1039b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1040b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam not associated"); 1041b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1042e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 104425ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande 104525ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande WifiConfigStore.ScanDetailCache scanDetailCache = 104625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande mWifiConfigStore.getScanDetailCache(current); 104725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande 104825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (scanDetailCache == null) { 1049b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1050b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam no scan cache"); 1051b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1052e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10534dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 105425ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (scanDetailCache.size() > 6) { 1055b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1056c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam scan cache size " 105725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande + scanDetailCache.size() + " --> bail"); 1058b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1059931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Implement same SSID roaming only for configurations 1060c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // that have less than 4 BSSIDs 1061e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1063b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 10642f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (current.BSSID != null && !current.BSSID.equals("any")) { 1065b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 10662f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("attemptRoam() BSSID is set " 10672f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + current.BSSID + " -> bail"); 1068b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1069e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 10704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1072931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Determine which BSSID we want to associate to, taking account 1073c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // relative strength of 5 and 2.4 GHz BSSIDs 10742451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 10754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 107625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail sd : scanDetailCache.values()) { 107725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult b = sd.getScanResult(); 107897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost5 = 0; 107997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost5 = 0; 108097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost = 0; 108197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost = 0; 108225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if ((sd.getSeen() == 0) || (b.BSSID == null) 108325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande || ((nowMs - sd.getSeen()) > age) 1084e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.autoJoinStatus != ScanResult.ENABLED 1085e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.numIpConfigFailures > 8) { 10864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 10873a2a3d226881cce8a4e511302231d843b0def303vandwalle } 10884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1089931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Pick first one 10904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (a == null) { 10914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle a = b; 10924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 10934dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1095e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (b.numIpConfigFailures < (a.numIpConfigFailures - 1)) { 1096e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // Prefer a BSSID that doesn't have less number of Ip config failures 1097e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptRoam: " 1098e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + b.BSSID + " rssi=" + b.level + " ipfail=" +b.numIpConfigFailures 1099e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + b.frequency 1100e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " > " 1101e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + a.BSSID + " rssi=" + a.level + " ipfail=" +a.numIpConfigFailures 1102e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + a.frequency); 1103e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle a = b; 1104e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle continue; 1105e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1106e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 11072451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply hysteresis: we favor the currentBSSID by giving it a boost 11087806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(b.BSSID)) { 1109931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 111077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (b.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 11110eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1112c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 11130eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1114c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 11154dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11167806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(a.BSSID)) { 111777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (a.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 1118931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 11190eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1120c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 11210eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1122c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 11234dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11242451dbcc4f9641df188326215b204b798eb70c46vandwalle 112597b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve 11262451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost the BSSID if it is on 5GHz, above a threshold 11272451dbcc4f9641df188326215b204b798eb70c46vandwalle // But penalize it if it is on 5GHz and below threshold 112897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // 112997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // With he current threshold values, 5GHz network with RSSI above -55 113097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Are given a boost of 30DB which is enough to overcome the current BSSID 113197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases 11329f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // 11339f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // The "current BSSID" Boost must be added to the BSSID's level so as to introduce\ 11349f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // soem amount of hysteresis 1135e67ec726c07410073575473c0f50dc737629f5davandwalle if (b.is5GHz()) { 11369f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.level + bRssiBoost, b.BSSID); 11374dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1138e67ec726c07410073575473c0f50dc737629f5davandwalle if (a.is5GHz()) { 11399f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.level + aRssiBoost, a.BSSID); 11404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11414dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 11424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 1143c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle String comp = " < "; 1144c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1145c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle comp = " > "; 1146c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 11474dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptRoam: " 1148c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost) 114997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency 115097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + comp 1151c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost) 1152c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency); 1153c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 1154c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle 11552451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare the RSSIs after applying the hysteresis boost and the 5GHz 11562451dbcc4f9641df188326215b204b798eb70c46vandwalle // boost if applicable 1157c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1158931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // b is the better BSSID 1159c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle a = b; 11604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11623a2a3d226881cce8a4e511302231d843b0def303vandwalle if (a != null) { 11633a2a3d226881cce8a4e511302231d843b0def303vandwalle if (VDBG) { 11647806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle StringBuilder sb = new StringBuilder(); 1165e67ec726c07410073575473c0f50dc737629f5davandwalle sb.append("attemptRoam: " + current.configKey() + 1166e67ec726c07410073575473c0f50dc737629f5davandwalle " Found " + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency); 11677806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null) { 11687806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append(" Current: " + currentBSSID); 11697806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 11707806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append("\n"); 11717806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle logDbg(sb.toString()); 11723a2a3d226881cce8a4e511302231d843b0def303vandwalle } 11734dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11743a2a3d226881cce8a4e511302231d843b0def303vandwalle return a; 11754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1177931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 11782451dbcc4f9641df188326215b204b798eb70c46vandwalle * getNetworkScore() 11792451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11802451dbcc4f9641df188326215b204b798eb70c46vandwalle * if scorer is present, get the network score of a WifiConfiguration 11812451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11822451dbcc4f9641df188326215b204b798eb70c46vandwalle * Note: this should be merge with setVisibility 11832451dbcc4f9641df188326215b204b798eb70c46vandwalle * 11842451dbcc4f9641df188326215b204b798eb70c46vandwalle * @param config 11852451dbcc4f9641df188326215b204b798eb70c46vandwalle * @return score 11862451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 118781c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int getConfigNetworkScore(WifiConfiguration config, int age, boolean isActive) { 11882451dbcc4f9641df188326215b204b798eb70c46vandwalle 11892451dbcc4f9641df188326215b204b798eb70c46vandwalle if (mNetworkScoreCache == null) { 1190e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1191b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1192e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scorer, hence no scores"); 1193e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 11941db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 11951db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 119625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande 119725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (mWifiConfigStore.getScanDetailCache(config) == null) { 1198e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1199b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1200e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scan cache"); 1201e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 12021db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 12032451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12042451dbcc4f9641df188326215b204b798eb70c46vandwalle 12052451dbcc4f9641df188326215b204b798eb70c46vandwalle // Get current date 12062451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 12072451dbcc4f9641df188326215b204b798eb70c46vandwalle 12081db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle int startScore = -10000; 12091db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle 12102451dbcc4f9641df188326215b204b798eb70c46vandwalle // Run thru all cached scan results 121125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail sd : mWifiConfigStore.getScanDetailCache(config).values()) { 121225ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult result = sd.getScanResult(); 121325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if ((nowMs - sd.getSeen()) < age) { 121481c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int sc = mNetworkScoreCache.getNetworkScore(result, isActive); 12151db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (sc > startScore) { 12161db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = sc; 12172451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12182451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12192451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12201db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (startScore == -10000) { 12211db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 12221db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 1223e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1224e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (startScore == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 1225b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1226e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no available score"); 1227e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } else { 1228b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 122981c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson + " isActive=" + isActive 1230e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " score = " + Integer.toString(startScore)); 1231e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1232e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1233e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle 12341db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return startScore; 12352451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12362451dbcc4f9641df188326215b204b798eb70c46vandwalle 12372451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 12388639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson * Set whether connections to untrusted connections are allowed. 12398639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson */ 12408639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson void setAllowUntrustedConnections(boolean allow) { 12418639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson boolean changed = mAllowUntrustedConnections != allow; 12428639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson mAllowUntrustedConnections = allow; 12438639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (changed) { 1244005c1ef113192f898499a407dd266393a8d6b076vandwalle // Trigger a scan so as to reattempt autojoin 1245005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiStateMachine.startScanForUntrustedSettingChange(); 12468639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 12478639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 12488639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 12498639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean isOpenNetwork(ScanResult result) { 12508639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson return !result.capabilities.contains("WEP") && 12518639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("PSK") && 12528639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("EAP"); 12538639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 12548639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 125516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private boolean haveRecentlySeenScoredBssid(WifiConfiguration config) { 125616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long ephemeralOutOfRangeTimeoutMs = Settings.Global.getLong( 125716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson mContext.getContentResolver(), 125816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson Settings.Global.WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS, 125916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS); 126016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 126116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Check whether the currently selected network has a score curve. If 126216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // ephemeralOutOfRangeTimeoutMs is <= 0, then this is all we check, and we stop here. 126316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Otherwise, we stop here if the currently selected network has a score. If it doesn't, we 126416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // keep going - it could be that another BSSID is in range (has been seen recently) which 126516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // has a score, even if the one we're immediately connected to doesn't. 126616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson ScanResult currentScanResult = mWifiStateMachine.getCurrentScanResult(); 126716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson boolean currentNetworkHasScoreCurve = mNetworkScoreCache.hasScoreCurve(currentScanResult); 126816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (ephemeralOutOfRangeTimeoutMs <= 0 || currentNetworkHasScoreCurve) { 126916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 127016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (currentNetworkHasScoreCurve) { 127116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has a score curve, keeping network: " 127216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson + currentScanResult); 127316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } else { 127416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has no score curve, giving up: " + config.SSID); 127516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 127616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 127716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return currentNetworkHasScoreCurve; 127816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 127916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 128025ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (mWifiConfigStore.getScanDetailCache(config) == null 128125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande || mWifiConfigStore.getScanDetailCache(config).isEmpty()) { 128216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 128316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 128416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 128516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long currentTimeMs = System.currentTimeMillis(); 128625ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail sd : mWifiConfigStore.getScanDetailCache(config).values()) { 128725ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult result = sd.getScanResult(); 128825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande if (currentTimeMs > sd.getSeen() 128925ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande && currentTimeMs - sd.getSeen() < ephemeralOutOfRangeTimeoutMs 129016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson && mNetworkScoreCache.hasScoreCurve(result)) { 129116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 129216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Found scored BSSID, keeping network: " + result.BSSID); 129316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 129416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return true; 129516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 129616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 129716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 129816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 129916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("No recently scored BSSID found, giving up connection: " + config.SSID); 130016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 130116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 130216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 130316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 130477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // After WifiStateMachine ask the supplicant to associate or reconnect 130577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // we might still obtain scan results from supplicant 130677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // however the supplicant state in the mWifiInfo and supplicant state tracker 130777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // are updated when we get the supplicant state change message which can be 130877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // processed after the SCAN_RESULT message, so at this point the framework doesn't 130977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // know that supplicant is ASSOCIATING. 131077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // A good fix for this race condition would be for the WifiStateMachine to add 131177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // a new transient state where it expects to get the supplicant message indicating 131277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // that it started the association process and within which critical operations 131377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // like autojoin should be deleted. 131477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 131577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // This transient state would remove the need for the roam Wathchdog which 131677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // basically does that. 131777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 131877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // At the moment, we just query the supplicant state synchronously with the 131977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // mWifiNative.status() command, which allow us to know that 132077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // supplicant has started association process, even though we didnt yet get the 132177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // SUPPLICANT_STATE_CHANGE message. 132277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 132377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final List<String> ASSOC_STATES = Arrays.asList( 132477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "ASSOCIATING", 132577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "ASSOCIATED", 132677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "FOUR_WAY_HANDSHAKE", 132777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "GROUP_KEY_HANDSHAKE"); 132877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 132977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private int getNetID(String wpaStatus) { 133077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (VDBG) { 133177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() status=" + wpaStatus); 133277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 133377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 133477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist try { 133577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int id = WifiConfiguration.INVALID_NETWORK_ID; 133677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String state = null; 133777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist BufferedReader br = new BufferedReader(new StringReader(wpaStatus)); 133877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String line; 133977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist while((line = br.readLine()) != null) { 134077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int split = line.indexOf('='); 134177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (split < 0) { 134277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist continue; 134377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 134477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 134577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String name = line.substring(0, split); 134677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (name.equals("id")) { 134777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist try { 134877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist id = Integer.parseInt(line.substring(split+1)); 134977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (state != null) { 135077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist break; 135177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 135277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 135377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist catch (NumberFormatException nfe) { 135477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Log.d("HS2J", "NFE on '" + line + "'"); 135577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; 135677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 135777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 135877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist else if (name.equals("wpa_state")) { 135977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist state = line.substring(split+1); 136077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Log.d("HS2J", "State: '" + line + "'"); 136177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (ASSOC_STATES.contains(state)) { 136277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; 136377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 136477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist else if (id >= 0) { 136577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist break; 136677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 136777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 136877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 136977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return id; 137077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 137177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist catch (IOException ioe) { 137277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; // Won't happen 137377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 137477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 137577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 137677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private boolean setCurrentConfigurationKey(WifiConfiguration currentConfig, 137777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int supplicantNetId) { 137877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (currentConfig != null) { 137977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (supplicantNetId != currentConfig.networkId 138077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // https://b.corp.google.com/issue?id=16484607 138177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // mark this condition as an error only if the mismatched networkId are valid 138277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID 138377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && currentConfig.networkId != WifiConfiguration.INVALID_NETWORK_ID) { 138477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 138577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(supplicantNetId) + " WifiStateMachine=" 138677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(currentConfig.networkId)); 138777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiStateMachine.disconnectCommand(); 138877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 138977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else if (currentConfig.ephemeral && (!mAllowUntrustedConnections || 139077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist !haveRecentlySeenScoredBssid(currentConfig))) { 139177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // The current connection is untrusted (the framework added it), but we're either 139277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // no longer allowed to connect to such networks, the score has been nullified 139377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // since we connected, or the scored BSSID has gone out of range. 139477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Drop the current connection and perform the rest of autojoin. 139577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network"); 139677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiStateMachine.disconnectCommand(Process.WIFI_UID, 139777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAllowUntrustedConnections ? 1 : 0); 139877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 139977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 140077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCurrentConfigurationKey = currentConfig.configKey(); 140177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return true; 140277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 140477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // If not invalid, then maybe in the process of associating, skip this attempt 140577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return supplicantNetId == WifiConfiguration.INVALID_NETWORK_ID; 140677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 140977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private void updateBlackListStatus(WifiConfiguration config, long now) { 141077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Wait for 5 minutes before reenabling config that have known, 141177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // repeated connection or DHCP failures 141277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE 141377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || config.disableReason 141477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist == WifiConfiguration.DISABLED_ASSOCIATION_REJECT 141577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || config.disableReason 141677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist == WifiConfiguration.DISABLED_AUTH_FAILURE) { 141777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.blackListTimestamp == 0 141877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || (config.blackListTimestamp > now)) { 141977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Sanitize the timestamp 142077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.blackListTimestamp = now; 142177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 142277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if ((now - config.blackListTimestamp) > 142377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.wifiConfigBlacklistMinTimeMilli) { 142477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Re-enable the WifiConfiguration 142577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.status = WifiConfiguration.Status.ENABLED; 142677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 142777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Reset the blacklist condition 142877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numConnectionFailures = 0; 142977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numIpConfigFailures = 0; 143077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numAuthFailures = 0; 143177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 143277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 143377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.dirty = true; 143477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 143577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (VDBG) { 143677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist long delay = mWifiConfigStore.wifiConfigBlacklistMinTimeMilli 143777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist - (now - config.blackListTimestamp); 143877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptautoJoin " + config.configKey() 143977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + " dont unblacklist yet, waiting for " 144077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + delay + " ms"); 144177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 144277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 144377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 144477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Avoid networks disabled because of AUTH failure altogether 144577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (DBG) { 144677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin skip candidate due to auto join status " 144777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(config.autoJoinStatus) + " key " 144877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + config.configKey(true) 144977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + " reason " + config.disableReason); 145077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 145177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 145277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 145377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underSoftThreshold(WifiConfiguration config) { 145477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Soft.get() 145577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Soft.get(); 145677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 145777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 145877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underHardThreshold(WifiConfiguration config) { 145977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Hard.get() 146077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Hard.get(); 146177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 146277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 146377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underThreshold(WifiConfiguration config, int rssi24, int rssi5) { 146477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < rssi24 && config.visibility.rssi5 < rssi5; 146577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 146677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 14678639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** 1468931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * attemptAutoJoin() function implements the core of the a network switching algorithm 146968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle * Return false if no acceptable networks were found. 1470931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 147168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean attemptAutoJoin() { 147268fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean found = false; 1473c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = false; 14741ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = false; 1475b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkSwitchType = AUTO_JOIN_IDLE; 14764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 14778242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 14788242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle 14798c9088d11880553458f09377cc60d6eb7e66747bvandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 14808c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1481931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reset the currentConfiguration Key, and set it only if WifiStateMachine and 1482453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 1483453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 1484453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 1485453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1486f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 1487f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1488931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Obtain the subset of recently seen networks 1489833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle List<WifiConfiguration> list = 1490833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.getRecentConfiguredNetworks(mScanResultAutoJoinAge, false); 1491f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 14922f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) logDbg("attemptAutoJoin nothing known=" + 149325ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande mWifiConfigStore.getConfiguredNetworkSize()); 149468fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1495f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1496f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1497931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Find the currently connected network: ask the supplicant directly 149877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 149977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int supplicantNetId = getNetID(mWifiNative.status(true)); 150077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1501ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 15027806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle String conf = ""; 1503b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String last = ""; 15047806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentConfiguration != null) { 1505e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle conf = " current=" + currentConfiguration.configKey(); 1506b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1507b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (lastSelectedConfiguration != null) { 15082f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle last = " last=" + lastSelectedConfiguration; 15097806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 1510ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 1511b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + conf + last 1512b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " ---> suppNetId=" + Integer.toString(supplicantNetId)); 1513ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1514f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 151577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (!setCurrentConfigurationKey(currentConfiguration, supplicantNetId)) { 151677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 1517453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 1518453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1519b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int currentNetId = -1; 1520b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentConfiguration != null) { 1521931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If we are associated to a configuration, it will 1522b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // be compared thru the compareNetwork function 1523b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle currentNetId = currentConfiguration.networkId; 1524b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 1525b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle 1526931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1527931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Run thru all visible configurations without looking at the one we 1528c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle * are currently associated to 15294dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * select Best Network candidate from known WifiConfigurations 1530931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1531f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 1532e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 1533b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle continue; 1534e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 1535e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 153677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.autoJoinStatus >= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) { 153777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist updateBlackListStatus(config, now); 1538f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1539f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1540f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1541931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to un-blacklist based on elapsed time 154227355a942653264388e909a4276196ee63e57811vandwalle if (config.blackListTimestamp > 0) { 154327355a942653264388e909a4276196ee63e57811vandwalle if (now < config.blackListTimestamp) { 1544931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1545931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * looks like there was a change in the system clock since we black listed, and 1546931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * timestamp is not meaningful anymore, hence lose it. 1547931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * this event should be rare enough so that we still want to lose the black list 15482451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 154927355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 155027355a942653264388e909a4276196ee63e57811vandwalle } else { 15514dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now - config.blackListTimestamp) > loseBlackListHardMilli) { 1552931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable it after 18 hours, i.e. next day 155327355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 15544dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) { 1555931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose blacklisting due to bad link 155627355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 8); 155727355a942653264388e909a4276196ee63e57811vandwalle } 155827355a942653264388e909a4276196ee63e57811vandwalle } 155927355a942653264388e909a4276196ee63e57811vandwalle } 156027355a942653264388e909a4276196ee63e57811vandwalle 156177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.visibility == null) { 156277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist continue; 156377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 156477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1565931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to unblacklist based on good visibility 156677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (underSoftThreshold(config)) { 156777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin do not unblacklist due to low visibility ", config); 156877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else if (underHardThreshold(config)) { 1569931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If the network is simply temporary disabled, don't allow reconnect until 1570931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // RSSI becomes good enough 157127355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 1); 157277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin good candidate seen, bumped soft -> status=", config); 157327355a942653264388e909a4276196ee63e57811vandwalle } else { 1574c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 3); 157577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin good candidate seen, bumped hard -> status=", config); 157627355a942653264388e909a4276196ee63e57811vandwalle } 157727355a942653264388e909a4276196ee63e57811vandwalle 157827355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 157927355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 1580931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Network is blacklisted, skip 158177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin skip blacklisted -> status=", config); 158227355a942653264388e909a4276196ee63e57811vandwalle continue; 158327355a942653264388e909a4276196ee63e57811vandwalle } 1584f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 1585ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 158621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("attemptAutoJoin skip current candidate " 158721bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle + Integer.toString(currentNetId) 1588ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 1589ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1590f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1591f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1592f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 15930eebae7334d6129f7ca1344e4b20199794994358vandwalle boolean isLastSelected = false; 15940eebae7334d6129f7ca1344e4b20199794994358vandwalle if (lastSelectedConfiguration != null && 15950eebae7334d6129f7ca1344e4b20199794994358vandwalle config.configKey().equals(lastSelectedConfiguration)) { 15960eebae7334d6129f7ca1344e4b20199794994358vandwalle isLastSelected = true; 15970eebae7334d6129f7ca1344e4b20199794994358vandwalle } 15980eebae7334d6129f7ca1344e4b20199794994358vandwalle 15994fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (config.lastRoamingFailure != 0 16004fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && currentConfiguration != null 16014fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && (lastSelectedConfiguration == null 16024fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle || !config.configKey().equals(lastSelectedConfiguration))) { 16034fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // Apply blacklisting for roaming to this config if: 16044fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - the target config had a recent roaming failure 16054fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - we are currently associated 16064fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle // - the target config is not the last selected 16074fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (now > config.lastRoamingFailure 16084fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle && (now - config.lastRoamingFailure) 16094fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle < config.roamingFailureBlackListTimeMilli) { 16104fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle if (DBG) { 16114fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle logDbg("compareNetwork not switching to " + config.configKey() 16124fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " from current " + currentConfiguration.configKey() 16134fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " because it is blacklisted due to roam failure, " 16144fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + " blacklist remain time = " 16154fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle + (now - config.lastRoamingFailure) + " ms"); 16164fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 16174fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle continue; 16184fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 16194fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle } 16204fa99f57077ab287d6ed1b51cf308c44ce8bbe0bvandwalle 16211ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount; 162277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (underThreshold(config, 162377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.thresholdInitialAutoJoinAttemptMin24RSSI.get() - boost, 162477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI.get() - boost)) { 162577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 162677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin skip due to low visibility -> status=", config); 16270eebae7334d6129f7ca1344e4b20199794994358vandwalle 1628c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Don't try to autojoin a network that is too far but 1629c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If that configuration is a user's choice however, try anyway 16300eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!isLastSelected) { 16310eebae7334d6129f7ca1344e4b20199794994358vandwalle config.autoJoinBailedDueToLowRssi = true; 16321ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = true; 16338c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 16340eebae7334d6129f7ca1344e4b20199794994358vandwalle } else { 16350eebae7334d6129f7ca1344e4b20199794994358vandwalle // Next time, try to be a bit more aggressive in auto-joining 16360eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.autoJoinUseAggressiveJoinAttemptThreshold 1637dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle < WifiConfiguration.MAX_INITIAL_AUTO_JOIN_RSSI_BOOST 1638dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle && config.autoJoinBailedDueToLowRssi) { 1639dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle config.autoJoinUseAggressiveJoinAttemptThreshold += 4; 16404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 16418c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 16420eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1643d30127db46224e45554f8964209221bba8ad41d9vandwalle if (config.numNoInternetAccessReports > 0 1644d30127db46224e45554f8964209221bba8ad41d9vandwalle && !isLastSelected 1645d30127db46224e45554f8964209221bba8ad41d9vandwalle && !config.validatedInternetAccess) { 1646d30127db46224e45554f8964209221bba8ad41d9vandwalle // Avoid autoJoining this network because last time we used it, it didn't 1647d30127db46224e45554f8964209221bba8ad41d9vandwalle // have internet access, and we never manage to validate internet access on this 1648d30127db46224e45554f8964209221bba8ad41d9vandwalle // network configuration 16490eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 1650d30127db46224e45554f8964209221bba8ad41d9vandwalle logDbg("attemptAutoJoin skip candidate due to no InternetAccess " 1651d30127db46224e45554f8964209221bba8ad41d9vandwalle + config.configKey(true) 1652d30127db46224e45554f8964209221bba8ad41d9vandwalle + " num reports " + config.numNoInternetAccessReports); 16539f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 16540eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 16558c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 16568c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1657ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1658e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String cur = ""; 1659e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (candidate != null) { 1660e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle cur = " current candidate " + candidate.configKey(); 1661e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1662e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptAutoJoin trying id=" 1663c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Integer.toString(config.networkId) + " " 1664b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + config.configKey(true) 1665e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " status=" + config.autoJoinStatus 1666e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + cur); 1667ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1668f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1669f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 1670f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1671f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1672f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1673453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 16744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " with " + config.configKey()); 1675f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1676833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(candidate, config); 16772451dbcc4f9641df188326215b204b798eb70c46vandwalle 16782451dbcc4f9641df188326215b204b798eb70c46vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 1679c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 16802451dbcc4f9641df188326215b204b798eb70c46vandwalle // enableNetwork with disableOthers=true WifiManager API 16812451dbcc4f9641df188326215b204b798eb70c46vandwalle // As this is a direct user choice, we strongly prefer this configuration, 16822451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence give +/-100 16832451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((lastSelectedConfiguration != null) 16842451dbcc4f9641df188326215b204b798eb70c46vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 16852451dbcc4f9641df188326215b204b798eb70c46vandwalle // candidate is the last selected configuration, 16862451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 16872451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 16882451dbcc4f9641df188326215b204b798eb70c46vandwalle // by reducing order by -100 16892451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - 100; 16902451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 16912f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers -100 " + candidate.configKey() 16922451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + config.configKey() 16932451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 16942451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 16952451dbcc4f9641df188326215b204b798eb70c46vandwalle } 16962451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if ((lastSelectedConfiguration != null) 16972451dbcc4f9641df188326215b204b798eb70c46vandwalle && config.configKey().equals(lastSelectedConfiguration)) { 16982451dbcc4f9641df188326215b204b798eb70c46vandwalle // config is the last selected configuration, 16992451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 17002451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 17012451dbcc4f9641df188326215b204b798eb70c46vandwalle // by increasing order by +100 17022451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + 100; 17032451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 17042f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers +100 " + config.configKey() 17052451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + candidate.configKey() 17062451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 17072451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 17082451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17092451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17102451dbcc4f9641df188326215b204b798eb70c46vandwalle 1711f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 1712931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Ascending : candidate < config 1713f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1714f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1715f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1716f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1717f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17182451dbcc4f9641df188326215b204b798eb70c46vandwalle // Now, go thru scan result to try finding a better untrusted network 1719833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if (mNetworkScoreCache != null && mAllowUntrustedConnections) { 1720f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 1721f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 1722f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 1723f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 1724f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 1725f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1726f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1727931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Get current date 17282451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 1729c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int currentScore = -10000; 1730c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // The untrusted network with highest score 173125ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanDetail untrustedCandidate = null; 17322451dbcc4f9641df188326215b204b798eb70c46vandwalle // Look for untrusted scored network only if the current candidate is bad 1733c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (isBadCandidate(rssi24, rssi5)) { 173425ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande for (ScanDetail scanDetail : scanResultCache.values()) { 173525ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande ScanResult result = scanDetail.getScanResult(); 1736c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We look only at untrusted networks with a valid SSID 1737c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // A trusted result would have been looked at thru it's Wificonfiguration 17388639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (TextUtils.isEmpty(result.SSID) || !result.untrusted || 17398639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !isOpenNetwork(result)) { 1740c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle continue; 1741c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 17422c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson String quotedSSID = "\"" + result.SSID + "\""; 17432c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains(quotedSSID)) { 17442ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle // SSID had been Forgotten by user, then don't score it 17452ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle continue; 17462ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle } 1747833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if ((nowMs - result.seen) < mScanResultAutoJoinAge) { 1748c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Increment usage count for the network 17492c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson mWifiConnectionStatistics.incrementOrAddUntrusted(quotedSSID, 0, 1); 1750c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 17512c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson boolean isActiveNetwork = currentConfiguration != null 17522c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson && currentConfiguration.SSID.equals(quotedSSID); 175381c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int score = mNetworkScoreCache.getNetworkScore(result, isActiveNetwork); 1754c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (score != WifiNetworkScoreCache.INVALID_NETWORK_SCORE 1755c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle && score > currentScore) { 1756c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Highest score: Select this candidate 1757c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle currentScore = score; 175825ee2d5d30434712b28aef6eec9460035101e493Vinit Deshpande untrustedCandidate = scanDetail; 1759c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (VDBG) { 1760c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("AutoJoinController: found untrusted candidate " 1761c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + result.SSID 1762c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " RSSI=" + result.level 1763c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " freq=" + result.frequency 1764c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " score=" + score); 1765c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1766f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1767f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1768f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1769f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1770c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (untrustedCandidate != null) { 17718639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // At this point, we have an untrusted network candidate. 17728639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // Create the new ephemeral configuration and see if we should switch over 1773833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate = 1774833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.wifiConfigurationFromScanResult(untrustedCandidate); 1775833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.allowedKeyManagement.set(KeyMgmt.NONE); 1776833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.ephemeral = true; 1777c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1778c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1779b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 17801ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle long lastUnwanted = 17811ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle System.currentTimeMillis() 17821ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle - mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp; 17831ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (candidate == null 17841ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && lastSelectedConfiguration == null 17851ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && currentConfiguration == null 17861ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && didBailDueToWeakRssi 17871ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && (mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp == 0 17881ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle || lastUnwanted > (1000 * 60 * 60 * 24 * 7)) 17891ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle ) { 17901ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // We are bailing out of autojoin although we are seeing a weak configuration, and 17911ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we didn't find another valid candidate 17921ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we are not connected 17931ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - without a user network selection choice 17941ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - ConnectivityService has not triggered an unwanted network disconnect 17951ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // on this device for a week (hence most likely there is no SIM card or cellular) 17961ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // If all those conditions are met, then boost the RSSI of the weak networks 17971ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // that we are seeing so as we will eventually pick one 17981ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount < 10) 17991ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount += 1; 18001ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } else { 18011ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount > 0) 18021ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount -= 1; 18031ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } 18041ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 1805931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1806931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * If candidate is found, check the state of the connection so as 1807931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * to decide if we should be acting on this candidate and switching over 1808931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1809e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle int networkDelta = compareNetwork(candidate, lastSelectedConfiguration); 1810b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (DBG && candidate != null) { 1811b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String doSwitch = ""; 1812b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String current = ""; 1813b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (networkDelta < 0) { 1814b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle doSwitch = " -> not switching"; 1815b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1816b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (currentConfiguration != null) { 18172f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle current = " with current " + currentConfiguration.configKey(); 1818b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1819b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("attemptAutoJoin networkSwitching candidate " 1820b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + candidate.configKey() 1821b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + current 1822c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + " linked=" + (currentConfiguration != null 1823b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle && currentConfiguration.isLinked(candidate)) 1824b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " : delta=" 1825b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + Integer.toString(networkDelta) + " " 1826b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + doSwitch); 1827b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18284dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1829931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1830931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Ask WifiStateMachine permission to switch : 1831931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * if user is currently streaming voice traffic, 1832931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * then we should not be allowed to switch regardless of the delta 1833931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 183477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) { // !!! JNo: Here! 1835b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mStaStaSupported) { 1836b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("mStaStaSupported --> error do nothing now "); 1837b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1838b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) { 1839b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING; 1840b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1841b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING; 1842b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1843b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1844b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto connect with netId " 1845b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(candidate.networkId) 1846b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " to " + candidate.configKey()); 1847b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18482451dbcc4f9641df188326215b204b798eb70c46vandwalle if (didOverride) { 18492451dbcc4f9641df188326215b204b798eb70c46vandwalle candidate.numScorerOverrideAndSwitchedNetwork++; 18502451dbcc4f9641df188326215b204b798eb70c46vandwalle } 1851c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle candidate.numAssociation++; 1852e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoJoinAttempt++; 18539f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 18542c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson if (candidate.ephemeral) { 18552c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson // We found a new candidate that we are going to connect to, then 18562c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson // increase its connection count 18572c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson mWifiConnectionStatistics. 18582c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson incrementOrAddUntrusted(candidate.SSID, 1, 0); 18592c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson } 18602c9b6297f3cd74780a084634320d03a413a3b779Jeff Davidson 18612f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (candidate.BSSID == null || candidate.BSSID.equals("any")) { 18622f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // First step we selected the configuration we want to connect to 18632f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Second step: Look for the best Scan result for this configuration 18642f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // TODO this algorithm should really be done in one step 18652f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1866833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1867833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, candidate, mScanResultAutoJoinAge, null); 18682f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && currentBSSID != null 18692f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 18702f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Sanity, we were already asociated to that candidate 18712f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle roamCandidate = null; 18722f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 18732f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && roamCandidate.is5GHz()) { 18742f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // If the configuration hasn't a default BSSID selected, and the best 18752f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // candidate is 5GHZ, then select this candidate so as WifiStateMachine and 18762f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // supplicant will pick it first 18772f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle candidate.autoJoinBSSID = roamCandidate.BSSID; 18782f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) { 18792f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("AutoJoinController: lock to 5GHz " 18802f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + candidate.autoJoinBSSID 18812f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " RSSI=" + roamCandidate.level 18822f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " freq=" + roamCandidate.frequency); 18832f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 1884448c9536a302c58a79e271b1721c08b8882f800evandwalle } else { 1885448c9536a302c58a79e271b1721c08b8882f800evandwalle // We couldnt find a roam candidate 1886448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.autoJoinBSSID = "any"; 18879f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 18889f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1889448c9536a302c58a79e271b1721c08b8882f800evandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 1890448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.networkId, networkSwitchType, candidate); 189168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 18924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1893b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1895b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (networkSwitchType == AUTO_JOIN_IDLE) { 1896e67ec726c07410073575473c0f50dc737629f5davandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1897931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Attempt same WifiConfiguration roaming 1898833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1899833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, currentConfiguration, mScanResultAutoJoinAge, currentBSSID); 1900e67ec726c07410073575473c0f50dc737629f5davandwalle /** 1901e67ec726c07410073575473c0f50dc737629f5davandwalle * TODO: (post L initial release) 1902e67ec726c07410073575473c0f50dc737629f5davandwalle * consider handling linked configurations roaming (i.e. extended Roaming) 1903e67ec726c07410073575473c0f50dc737629f5davandwalle * thru the attemptRoam function which makes use of the RSSI roaming threshold. 1904e67ec726c07410073575473c0f50dc737629f5davandwalle * At the moment, extended roaming is only handled thru the attemptAutoJoin() 1905e67ec726c07410073575473c0f50dc737629f5davandwalle * function which compare configurations. 1906e67ec726c07410073575473c0f50dc737629f5davandwalle * 1907e67ec726c07410073575473c0f50dc737629f5davandwalle * The advantage of making use of attemptRoam function is that this function 1908e67ec726c07410073575473c0f50dc737629f5davandwalle * will looks at all the BSSID of each configurations, instead of only looking 1909e67ec726c07410073575473c0f50dc737629f5davandwalle * at WifiConfiguration.visibility which keeps trackonly of the RSSI/band of the 1910e67ec726c07410073575473c0f50dc737629f5davandwalle * two highest BSSIDs. 1911e67ec726c07410073575473c0f50dc737629f5davandwalle */ 1912e67ec726c07410073575473c0f50dc737629f5davandwalle // Attempt linked WifiConfiguration roaming 1913e67ec726c07410073575473c0f50dc737629f5davandwalle /* if (currentConfiguration != null 1914e67ec726c07410073575473c0f50dc737629f5davandwalle && currentConfiguration.linkedConfigurations != null) { 1915e67ec726c07410073575473c0f50dc737629f5davandwalle for (String key : currentConfiguration.linkedConfigurations.keySet()) { 1916e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration link = mWifiConfigStore.getWifiConfiguration(key); 1917e67ec726c07410073575473c0f50dc737629f5davandwalle if (link != null) { 1918833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle roamCandidate = attemptRoam(roamCandidate, link, mScanResultAutoJoinAge, 1919e67ec726c07410073575473c0f50dc737629f5davandwalle currentBSSID); 1920e67ec726c07410073575473c0f50dc737629f5davandwalle } 1921e67ec726c07410073575473c0f50dc737629f5davandwalle } 1922e67ec726c07410073575473c0f50dc737629f5davandwalle }*/ 1923e67ec726c07410073575473c0f50dc737629f5davandwalle if (roamCandidate != null && currentBSSID != null 1924e67ec726c07410073575473c0f50dc737629f5davandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 1925e67ec726c07410073575473c0f50dc737629f5davandwalle roamCandidate = null; 1926e67ec726c07410073575473c0f50dc737629f5davandwalle } 19272f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && mWifiStateMachine.shouldSwitchNetwork(999)) { 1928b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1929b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto roam with netId " 1930b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(currentConfiguration.networkId) 1931b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " " + currentConfiguration.configKey() + " to BSSID=" 1932b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + roamCandidate.BSSID + " freq=" + roamCandidate.frequency 19331ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle + " RSSI=" + roamCandidate.level); 1934b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1935b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_ROAMING; 1936e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoRoamAttempt++; 1937e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 1938b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM, 1939b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle currentConfiguration.networkId, 1, roamCandidate); 194068fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 1941f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1942f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1943b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType)); 194468fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return found; 1945f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 194677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 194777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private void logDenial(String reason, WifiConfiguration config) { 194877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (!DBG) { 194977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return; 195077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 195177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg(reason + config.toString()); 195277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 1953f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 1954f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1955