WifiAutoJoinController.java revision ef1567e413c9ed5f5c4fdb9e354861632f7b2f87
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; 48ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport java.util.Collection; 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 5077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Iterator; 51f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 52ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvistimport java.util.Map; 53f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 54f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 56f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 57f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 58f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 59f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 60f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 62f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 63f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 64f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 65f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 66f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 67f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 68f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 69f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 70f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 71ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean DBG = false; 72ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 73f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 74f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 75c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle public static int mScanResultMaximumAge = 40000; /* milliseconds unit */ 76833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle public static int mScanResultAutoJoinAge = 5000; /* milliseconds unit */ 77c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 78453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 79f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final HashMap<String, ScanResult> scanResultCache = new HashMap<>(); 81f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 82c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle private WifiConnectionStatistics mWifiConnectionStatistics; 83c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 848639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** Whether to allow connections to untrusted networks. */ 858639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean mAllowUntrustedConnections = false; 868639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 87c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle /* for debug purpose only : the untrusted SSID we would be connected to if we had VPN */ 88c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle String lastUntrustedBSSID = null; 89c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 90c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /* For debug purpose only: if the scored override a score */ 91c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle boolean didOverride = false; 92c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 93931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose the non-auth failure blacklisting after 8 hours 944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListHardMilli = 1000 * 60 * 60 * 8; 95931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose some temporary blacklisting after 30 minutes 964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListSoftMilli = 1000 * 60 * 30; 9727355a942653264388e909a4276196ee63e57811vandwalle 9816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson /** @see android.provider.Settings.Global#WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS */ 9916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private static final long DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS = 1000 * 60; // 1 minute 10016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 101b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_IDLE = 0; 102b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_ROAMING = 1; 103b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_EXTENDED_ROAMING = 2; 104b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3; 105b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 10697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle public static final int HIGH_THRESHOLD_MODIFIER = 5; 10797b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle 1081ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // Below are AutoJoin wide parameters indicating if we should be aggressive before joining 1091ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // weak network. Note that we cannot join weak network that are going to be marked as unanted by 1101ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // ConnectivityService because this will trigger link flapping. 1111ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 1121ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * There was a non-blacklisted configuration that we bailed from because of a weak signal 1131ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 1141ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle boolean didBailDueToWeakRssi = false; 1151ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle /** 1161ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * number of time we consecutively bailed out of an eligible network because its signal 1171ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle * was too weak 1181ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle */ 1191ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int weakRssiBailCount = 0; 1201ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 121ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private final AnqpCache mAnqpCache; 122ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private final SupplicantBridge mSupplicantBridge; 123ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private final List<PasspointMatchInfo> mMatchInfoList; 124ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 125f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 126c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle WifiConnectionStatistics st, WifiNative n) { 127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 128f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 131f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 132c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics = st; 13321bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle scoreManager = 13421bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 138f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 139f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 140f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 141f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 142f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 143f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 144f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 145f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 146f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 147ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 148ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mMatchInfoList = new ArrayList<>(); 149ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Chronograph chronograph = new Chronograph(); 150ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mAnqpCache = new AnqpCache(chronograph); 151ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mSupplicantBridge = new SupplicantBridge(mWifiNative, this); 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 154ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 155ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (verbose > 0 ) { 156abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = true; 157ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 158ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 159abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = false; 160ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 161ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 162ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 163ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 164931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 165931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Flush out scan results older than mScanResultMaximumAge 166ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * 167931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 169f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 170931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle delay = mScanResultMaximumAge; // Something sane 171f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 172b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long milli = System.currentTimeMillis(); 173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 174f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 177f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 178f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Iterator<HashMap.Entry<String,ScanResult>> iter = scanResultCache.entrySet().iterator(); 179f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 180f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle HashMap.Entry<String,ScanResult> entry = iter.next(); 181f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult result = entry.getValue(); 182f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 183f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.seen + delay) < milli) { 184f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 185f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 186f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 187f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 188f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 189ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist // !!! JNo >> 190ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 191ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist // !!! Call from addToScanCache 192ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private ScanDetail scoreHSNetwork(ScanDetail scanDetail) { 193ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 194ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (!networkDetail.has80211uInfo()) { 195ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return null; 196ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 197ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist updateCache(scanDetail, networkDetail.getANQPElements()); 198ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 199ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Map<HomeSP, PasspointMatch> matches = matchNetwork(scanDetail, 200ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist networkDetail.getANQPElements() == null); 201ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (!matches.isEmpty()) { 202ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return scanDetail.score(matches); 203ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } else { 204ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return null; 205ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 206ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 207ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 208ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private Map<HomeSP, PasspointMatch> matchNetwork(ScanDetail scanDetail, boolean query) { 209ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 210ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 211ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist ANQPData anqpData = mAnqpCache.getEntry(networkDetail); 212ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 213ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Map<Constants.ANQPElementType, ANQPElement> anqpElements = 214ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist anqpData != null ? anqpData.getANQPElements() : null; 215ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 216ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist boolean queried = !query; 217ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Collection<HomeSP> homeSPs = mWifiConfigStore.getHomeSPs(); 218ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Map<HomeSP, PasspointMatch> matches = new HashMap<>(homeSPs.size()); 219ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist for (HomeSP homeSP : homeSPs) { 220ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist PasspointMatch match = homeSP.match(networkDetail, anqpElements); 221ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 222ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (match == PasspointMatch.Incomplete && networkDetail.isInterworking() && !queried) { 223ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (mAnqpCache.initiate(networkDetail)) { 224ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mSupplicantBridge.startANQP(scanDetail); 225ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 226ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist queried = true; 227ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 228ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist matches.put(homeSP, match); 229ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 230ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return matches; 231ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 232ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 233ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist public void notifyANQPDone(Long bssid, boolean success) { 234ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mSupplicantBridge.notifyANQPDone(bssid, success); 235ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 236ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 237ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist public void notifyANQPResponse(ScanDetail scanDetail, 238ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 239ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 240ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist updateCache(scanDetail, anqpElements); 241ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (anqpElements == null) { 242ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return; 243ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 244ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 245ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Map<HomeSP, PasspointMatch> matches = matchNetwork(scanDetail, false); 246ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Log.d("HS2J", scanDetail.getSSID() + " 2nd Matches: " + toMatchString(matches)); 247ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 248ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist for (Map.Entry<HomeSP, PasspointMatch> entry : matches.entrySet()) { 249ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mMatchInfoList.add( 250ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist new PasspointMatchInfo(entry.getValue(), scanDetail.getNetworkDetail(), 251ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist entry.getKey())); 252ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 253ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 254ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist //mWifiStateMachine.updateScanResults(scanDetail, matches); 255ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 256ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 257ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private void updateCache(ScanDetail scanDetail, Map<Constants.ANQPElementType, 258ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist ANQPElement> anqpElements) 259ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist { 260ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 261ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 262ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (anqpElements == null) { 263ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist ANQPData data = mAnqpCache.getEntry(networkDetail); 264ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist if (data != null) { 265ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist scanDetail.propagateANQPInfo(data.getANQPElements()); 266ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 267ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return; 268ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 269ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 270ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist mAnqpCache.update(networkDetail, anqpElements); 271ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 272ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist Log.d("HS2J", "Cached " + networkDetail.getBSSIDString() + 273ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist "/" + networkDetail.getAnqpDomainID()); 274ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist scanDetail.propagateANQPInfo(anqpElements); 275ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 276ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 277ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist private static String toMatchString(Map<HomeSP, PasspointMatch> matches) { 278ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist StringBuilder sb = new StringBuilder(); 279ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist for (Map.Entry<HomeSP, PasspointMatch> entry : matches.entrySet()) { 280ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist sb.append(' ').append(entry.getKey().getFQDN()).append("->").append(entry.getValue()); 281ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 282ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist return sb.toString(); 283ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist } 284ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 285ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist // !!! << JNo 286ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist 28777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int addToScanCache(List<ScanDetail> scanList) { 288be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown = 0; // Record number of scan results we knew about 289be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiConfiguration associatedConfig = null; 2907b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle boolean didAssociate = false; 2918242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 292f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 2930c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 2940c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 29577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist for(ScanDetail scanDetail: scanList) { 29677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ScanResult result = scanDetail.getScanResult(); 2971fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (result.SSID == null) continue; 298c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 299c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Make sure we record the last time we saw this result 300f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.seen = System.currentTimeMillis(); 301f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 302c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Fetch the previous instance for this result 303f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult sr = scanResultCache.get(result.BSSID); 304f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (sr != null) { 3058ccabb81ad304b80dc8eaa162fd322643461529bvandwalle if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 3068ccabb81ad304b80dc8eaa162fd322643461529bvandwalle && result.level == 0 3078ccabb81ad304b80dc8eaa162fd322643461529bvandwalle && sr.level < -20) { 3088ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // A 'zero' RSSI reading is most likely a chip problem which returns 3098ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // an unknown RSSI, hence ignore it 3108ccabb81ad304b80dc8eaa162fd322643461529bvandwalle result.level = sr.level; 3118ccabb81ad304b80dc8eaa162fd322643461529bvandwalle } 3128ccabb81ad304b80dc8eaa162fd322643461529bvandwalle 313931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If there was a previous cache result for this BSSID, average the RSSI values 314c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge); 315f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 316c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Remove the previous Scan Result - this is not necessary 317f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.remove(result.BSSID); 3188ccabb81ad304b80dc8eaa162fd322643461529bvandwalle } else if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 && result.level == 0) { 3198ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // A 'zero' RSSI reading is most likely a chip problem which returns 3208ccabb81ad304b80dc8eaa162fd322643461529bvandwalle // an unknown RSSI, hence initialize it to a sane value 3218ccabb81ad304b80dc8eaa162fd322643461529bvandwalle result.level = mWifiConfigStore.scanResultRssiLevelPatchUp; 322e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 323e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 324e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 325e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle WifiKey wkey; 326e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle // Quoted SSIDs are the only one valid at this stage 327e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle try { 328e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 329e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } catch (IllegalArgumentException e) { 330e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID + 331e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle "] ->skipping this network"); 332e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle wkey = null; 333e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 334e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (wkey != null) { 335e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle NetworkKey nkey = new NetworkKey(wkey); 336e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle //if we don't know this scan result then request a score from the scorer 337e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle unknownScanResults.add(nkey); 338e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 339e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 3407b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 3417b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 3427b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 343e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 3447b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is not scored"); 345e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 3460c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 347e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 3487b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle String cap = ""; 3497b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (result.capabilities != null) 3507b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle cap = result.capabilities; 351e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 352e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle logDbg(result.SSID + " " + result.BSSID + " rssi=" 3537b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle + result.level + " cap " + cap + " is scored : " + score); 3540c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 355f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 356f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 357e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // scanResultCache.put(result.BSSID, new ScanResult(result)); 358e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle scanResultCache.put(result.BSSID, result); 359be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // Add this BSSID to the scanResultCache of a Saved WifiConfiguration 3607b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = mWifiConfigStore.updateSavedNetworkHistory(result); 361f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 362be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // If not successful, try to associate this BSSID to an existing Saved WifiConfiguration 3637b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (!didAssociate) { 364be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle // We couldn't associate the scan result to a Saved WifiConfiguration 365c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Hence it is untrusted 366c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle result.untrusted = true; 367f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.associateWithConfiguration(result); 3681fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (associatedConfig != null && associatedConfig.SSID != null) { 369f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 370f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("addToScanCache save associated config " 3718242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + associatedConfig.SSID + " with " + result.SSID 3728242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " status " + associatedConfig.autoJoinStatus 3738242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " reason " + associatedConfig.disableReason 3748242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " tsp " + associatedConfig.blackListTimestamp 3758242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle + " was " + (now - associatedConfig.blackListTimestamp)); 376f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 377be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle mWifiStateMachine.sendMessage( 378be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle WifiStateMachine.CMD_AUTO_SAVE_NETWORK, associatedConfig); 3797b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle didAssociate = true; 380f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 3810d616ef3bf635dff8722e064c0be842676390ed8vandwalle } else { 3820d616ef3bf635dff8722e064c0be842676390ed8vandwalle // If the scan result has been blacklisted fir 18 hours -> unblacklist 3830d616ef3bf635dff8722e064c0be842676390ed8vandwalle if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { 3840d616ef3bf635dff8722e064c0be842676390ed8vandwalle result.setAutoJoinStatus(ScanResult.ENABLED); 3850d616ef3bf635dff8722e064c0be842676390ed8vandwalle } 386f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 3877b581f46f6c9bc6edf0edd287d47106712fb2144vandwalle if (didAssociate) { 388be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown++; 389a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate ++; 390a0708b09ad17b086c008ab100aec7143d7613c80vandwalle } else { 391a0708b09ad17b086c008ab100aec7143d7613c80vandwalle result.isAutoJoinCandidate = 0; 392be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 393f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 3940c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 3950c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 3960c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 3970c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 398931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Kick the score manager, we will get updated scores asynchronously 3990c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 4000c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 401be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 402f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 403f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 404f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 4050888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle logDbg(message, false); 406ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 407ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 408ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 409ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 4102f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle Log.e(TAG, message + " stack:" 411ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 412ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 413ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 414ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 415ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 4162f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle Log.e(TAG, message); 417ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 418f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 419f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 420931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Called directly from WifiStateMachine 421be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int newSupplicantResults(boolean doAutoJoin) { 422be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle int numScanResultsKnown; 42377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist List<ScanDetail> scanList = mWifiStateMachine.getScanResultsListNoCopyUnsync(); 424be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle numScanResultsKnown = addToScanCache(scanList); 425f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 426be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle if (DBG) { 427be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) 4282f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " known=" + numScanResultsKnown + " " 4299f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle + doAutoJoin); 430be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle } 4317806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (doAutoJoin) { 4327806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle attemptAutoJoin(); 4337806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 434005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 435be3095ed758fca076b9ccb9fdae48f7f865c078avandwalle return numScanResultsKnown; 436f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 437f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 438f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 439931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 440931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Not used at the moment 441f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 442f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 443f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 444f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 445f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 44777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist List<ScanDetail> scanList = null;//mWifiScanner.syncGetScanResultsList(); 448f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 449f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 450f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 451f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 452f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 453005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 454f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 455f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 456931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 457931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * network link quality changed, called directly from WifiTrafficPoller, 458931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * or by listening to Link Quality intent 459931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 460f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 461f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 462f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 463f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 464931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 465f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 466f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 467f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 468f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 469b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * Negatve return values from this functions are meaningless per se, just trying to 470b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * keep them distinct for debug purpose (i.e. -1, -2 etc...) 471931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 472e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle private int compareNetwork(WifiConfiguration candidate, 473e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String lastSelectedConfiguration) { 474b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (candidate == null) 475b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -3; 476b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 477f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 478b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentNetwork == null) { 479c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Return any absurdly high score, if we are not connected there is no current 480c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // network to... 481b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return 1000; 482b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 483f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 484f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 485b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -2; 486f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 487f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 488b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (DBG) { 489e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("compareNetwork will compare " + candidate.configKey() 490e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " with current " + currentNetwork.configKey()); 491b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 492833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 493e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 494e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 495e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 496e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // enableNetwork with disableOthers=true WifiManager API 497e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // As this is a direct user choice, we strongly prefer this configuration, 498e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // hence give +/-100 499e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if ((lastSelectedConfiguration != null) 500e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && currentNetwork.configKey().equals(lastSelectedConfiguration)) { 501e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // currentNetwork is the last selected configuration, 502e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 503e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 504e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by reducing order by -100 505e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order - 100; 506e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 507e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers -100 " + currentNetwork.configKey() 508e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + candidate.configKey() 509e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 510e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 511e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 512e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } else if ((lastSelectedConfiguration != null) 513e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 514e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // candidate is the last selected configuration, 515e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // so keep it above connect choices (+/-60) and 516e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 517e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // by increasing order by +100 518e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle order = order + 100; 519e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (VDBG) { 520e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg(" ...and prefers +100 " + candidate.configKey() 521e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " over " + currentNetwork.configKey() 522e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " because it is the last selected -> " 523e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + Integer.toString(order)); 524e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 525e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 526e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 527ede507649471f1113e9e1919812115ca5a6bc0c8vandwalle return order; 528f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 529f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 530ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 531ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 532ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 533ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 534ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 535ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 53662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 537ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 538ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 539ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param connect : if the update includes a connect 540931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 54162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 542f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 543f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 544c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + " no selected configuration!"); 545f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 546f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 547f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 548e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 549c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory nid=" + netId + 550c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle " no SSID in selected configuration!"); 551e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 552e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 553e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 55462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 555931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable autojoin for this network, 55662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 55727355a942653264388e909a4276196ee63e57811vandwalle selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 55862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 559e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle selected.dirty = true; 56062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 561f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 562992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG && userTriggered) { 563f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 564ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 565f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 566992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(selected.connectChoices.size()) 567992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 568f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 569ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 570992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(netId) 571992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 572f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 573f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 574f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 575ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 576ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 5772451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice = 0; 578c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int size = 0; 5799f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 5809f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // Reset the triggered disabled count, because user wanted to connect to this 5819f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // configuration, and we were not. 5829f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableLowRSSI = 0; 5839f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableBadRSSI = 0; 5849f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredWifiDisableNotHighRSSI = 0; 5859f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle selected.numUserTriggeredJoinAttempts++; 5869f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 58762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 58862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 589c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (networks != null) size = networks.size(); 590c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("updateConfigurationHistory found " + size + " networks"); 59162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 59262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 593992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG) { 594992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle logDbg("updateConfigurationHistory got " + config.SSID + " nid=" 595992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(config.networkId)); 596992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 597f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 59862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 599ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 60062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 60162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 602f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6032451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare RSSI values so as to evaluate the strength of the user preference 6042451dbcc4f9641df188326215b204b798eb70c46vandwalle int order = compareWifiConfigurationsRSSI(config, selected, null); 6052451dbcc4f9641df188326215b204b798eb70c46vandwalle 6062451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order < -30) { 6072451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is worse than the visible configuration 6082451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a strong choice so as autojoin cannot override this 6092451dbcc4f9641df188326215b204b798eb70c46vandwalle // for instance, the user has select a network 6102451dbcc4f9641df188326215b204b798eb70c46vandwalle // with 1 bar over a network with 3 bars... 6112451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 60; 6122451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -20) { 6132451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 50; 6142451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < -10) { 6152451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 40; 6162f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else if (order < 20) { 6172451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is about same or has a slightly better RSSI 6182451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence register a weaker choice, here a difference of at least +/-30 in 6192451dbcc4f9641df188326215b204b798eb70c46vandwalle // RSSI comparison triggered by autoJoin will override the choice 6202451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 30; 6212f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } else { 6222451dbcc4f9641df188326215b204b798eb70c46vandwalle // Selected configuration is better than the visible configuration 6232451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence we do not know if the user prefers this configuration strongly 6242451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; 62562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 626f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 627931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // The selected configuration was preferred over a recently seen config 628931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // hence remember the user's choice: 629931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // add the recently seen config to the selected's connectChoices array 630ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 631ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (selected.connectChoices == null) { 632ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle selected.connectChoices = new HashMap<String, Integer>(); 633ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 634ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 635ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory add a choice " + selected.configKey(true) 6360888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle + " over " + config.configKey(true) 6372451dbcc4f9641df188326215b204b798eb70c46vandwalle + " choice " + Integer.toString(choice)); 638cf5b8eb8a08c45bd4a82f1f4bb789c8a1b08744fvandwalle 6392451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer currentChoice = selected.connectChoices.get(config.configKey(true)); 6402f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (currentChoice != null) { 6412f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // User has made this choice multiple time in a row, so bump up a lot 6422f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle choice += currentChoice.intValue(); 6432451dbcc4f9641df188326215b204b798eb70c46vandwalle } 6442f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Add the visible config to the selected's connect choice list 6452f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle selected.connectChoices.put(config.configKey(true), choice); 646f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 64762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 648ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 649ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 65062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 651ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 652931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected from the recently seen config's connectChoice list 65362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 6540888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 6550888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (selected.linkedConfigurations != null) { 656931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Remove the selected's linked configuration from the 657931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // recently seen config's connectChoice list 6580888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle for (String key : selected.linkedConfigurations.keySet()) { 6590888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle config.connectChoices.remove(key); 6600888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 6610888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 66262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 663ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 664ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 6652451dbcc4f9641df188326215b204b798eb70c46vandwalle // We haven't found the configuration that the user just selected in our 6662451dbcc4f9641df188326215b204b798eb70c46vandwalle // scan cache. 6672451dbcc4f9641df188326215b204b798eb70c46vandwalle // In that case we will need a new scan before attempting to connect to this 6682451dbcc4f9641df188326215b204b798eb70c46vandwalle // configuration anyhow and thus we can process the scan results then. 669ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 670ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + selected.configKey()); 67162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 672f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 67362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 67462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 675ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 67662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 67762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 678f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 679f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 680992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle 681931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // TODO: write only if something changed 682992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (userTriggered || connect) { 683005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiConfigStore.writeKnownNetworkHistory(false); 684992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 685f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 686f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6872451dbcc4f9641df188326215b204b798eb70c46vandwalle int getConnectChoice(WifiConfiguration source, WifiConfiguration target) { 6882451dbcc4f9641df188326215b204b798eb70c46vandwalle Integer choice = null; 6892451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source == null || target == null) { 6902451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 691f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 692f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6932451dbcc4f9641df188326215b204b798eb70c46vandwalle if (source.connectChoices != null 6942451dbcc4f9641df188326215b204b798eb70c46vandwalle && source.connectChoices.containsKey(target.configKey(true))) { 6952451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = source.connectChoices.get(target.configKey(true)); 6962451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (source.linkedConfigurations != null) { 697f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 698f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 699f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 700f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 7012451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = config.connectChoices.get(target.configKey(true)); 702f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 703f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 704f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7052451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7062451dbcc4f9641df188326215b204b798eb70c46vandwalle 7072451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice == null) { 7082451dbcc4f9641df188326215b204b798eb70c46vandwalle //We didn't find the connect choice 7092451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 7102451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 7112451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice.intValue() < 0) { 7122451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = 20; // Compatibility with older files 7132451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7142451dbcc4f9641df188326215b204b798eb70c46vandwalle return choice.intValue(); 7152451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7162451dbcc4f9641df188326215b204b798eb70c46vandwalle } 7172451dbcc4f9641df188326215b204b798eb70c46vandwalle 718815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int compareWifiConfigurationsFromVisibility(WifiConfiguration a, int aRssiBoost, 719815788ba7838fc54310baed3deb9b95548e0ce69vandwalle WifiConfiguration b, int bRssiBoost) { 7202451dbcc4f9641df188326215b204b798eb70c46vandwalle 721815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int aRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) 722815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int bRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) 723815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 724815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int aScore = 0; 725815788ba7838fc54310baed3deb9b95548e0ce69vandwalle int bScore = 0; 726815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 727815788ba7838fc54310baed3deb9b95548e0ce69vandwalle boolean aPrefers5GHz = false; 728815788ba7838fc54310baed3deb9b95548e0ce69vandwalle boolean bPrefers5GHz = false; 7294dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 7302451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 731815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * Calculate a boost to apply to RSSI value of configuration we want to join on 5GHz: 732815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * Boost RSSI value of 5GHz bands iff the base value is better than threshold, 733815788ba7838fc54310baed3deb9b95548e0ce69vandwalle * penalize the RSSI value of 5GHz band iff the base value is lower than threshold 7342451dbcc4f9641df188326215b204b798eb70c46vandwalle * This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas 7352451dbcc4f9641df188326215b204b798eb70c46vandwalle * we prefer 2.4GHz otherwise. 7362451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 737815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.visibility.rssi5, a.configKey() + "->"); 738815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.visibility.rssi5, b.configKey() + "->"); 7392451dbcc4f9641df188326215b204b798eb70c46vandwalle 740815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for a 741f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility.rssi5 + aRssiBoost5 > a.visibility.rssi24) { 7422451dbcc4f9641df188326215b204b798eb70c46vandwalle // Prefer a's 5GHz 743815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aPrefers5GHz = true; 744815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 745815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 746815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Select which band to use for b 747815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (b.visibility.rssi5 + bRssiBoost5 > b.visibility.rssi24) { 748815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Prefer b's 5GHz 749815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bPrefers5GHz = true; 750815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 751815788ba7838fc54310baed3deb9b95548e0ce69vandwalle 752815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (aPrefers5GHz) { 753815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (bPrefers5GHz) { 754815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either 755815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // one, but directly compare the RSSI values, this improves stability, 756815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // since the 5GHz RSSI boost can introduce large fluctuations 757815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aScore = a.visibility.rssi5 + aRssiBoost; 758815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 759815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only a is on 5GHz, then apply the 5GHz preference boost to a 760815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aScore = a.visibility.rssi5 + aRssiBoost + aRssiBoost5; 761815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 7622451dbcc4f9641df188326215b204b798eb70c46vandwalle } else { 763815788ba7838fc54310baed3deb9b95548e0ce69vandwalle aScore = a.visibility.rssi24 + aRssiBoost; 764f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 7652451dbcc4f9641df188326215b204b798eb70c46vandwalle 766815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (bPrefers5GHz) { 767815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (aPrefers5GHz) { 768815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either 769815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // one, but directly compare the RSSI values, this improves stability, 770815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // since the 5GHz RSSI boost can introduce large fluctuations 771815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bScore = b.visibility.rssi5 + bRssiBoost; 772815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 773815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If only b is on 5GHz, then apply the 5GHz preference boost to b 774815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bScore = b.visibility.rssi5 + bRssiBoost + bRssiBoost5; 775815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 776815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } else { 777815788ba7838fc54310baed3deb9b95548e0ce69vandwalle bScore = b.visibility.rssi24 + bRssiBoost; 778815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 779815788ba7838fc54310baed3deb9b95548e0ce69vandwalle if (VDBG) { 780815788ba7838fc54310baed3deb9b95548e0ce69vandwalle logDbg(" " + a.configKey() + " is5=" + aPrefers5GHz + " score=" + aScore 781f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " " + b.configKey() + " is5=" + bPrefers5GHz + " score=" + bScore); 782815788ba7838fc54310baed3deb9b95548e0ce69vandwalle } 783f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 784f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle // Debug only, record RSSI comparison parameters 785f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility != null) { 786f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.score = aScore; 787f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.currentNetworkBoost = aRssiBoost; 788f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.bandPreferenceBoost = aRssiBoost5; 789f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 790f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (b.visibility != null) { 791f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.score = bScore; 792f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.currentNetworkBoost = bRssiBoost; 793f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.bandPreferenceBoost = bRssiBoost5; 794f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 795f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle 796815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // Compare a and b 797815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If a score is higher then a > b and the order is descending (negative) 798815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // If b score is higher then a < b and the order is ascending (positive) 799815788ba7838fc54310baed3deb9b95548e0ce69vandwalle return bScore - aScore; 800f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 801f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 8022451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50] 8032451dbcc4f9641df188326215b204b798eb70c46vandwalle // The result represents "approximately" an RSSI difference measured in dBM 8042451dbcc4f9641df188326215b204b798eb70c46vandwalle // Adjusted with various parameters: 8052451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) current network gets a +15 boost 8062451dbcc4f9641df188326215b204b798eb70c46vandwalle // +) 5GHz signal, if they are strong enough, get a +15 or +25 boost, representing the 8072451dbcc4f9641df188326215b204b798eb70c46vandwalle // fact that at short range we prefer 5GHz band as it is cleaner of interference and 8082451dbcc4f9641df188326215b204b798eb70c46vandwalle // provides for wider channels 8092451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b, 8102451dbcc4f9641df188326215b204b798eb70c46vandwalle String currentConfiguration) { 811f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 8122451dbcc4f9641df188326215b204b798eb70c46vandwalle 8132451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost used so as to favor current config 8142451dbcc4f9641df188326215b204b798eb70c46vandwalle int aRssiBoost = 0; 8152451dbcc4f9641df188326215b204b798eb70c46vandwalle int bRssiBoost = 0; 8162451dbcc4f9641df188326215b204b798eb70c46vandwalle 8172451dbcc4f9641df188326215b204b798eb70c46vandwalle int scoreA; 8182451dbcc4f9641df188326215b204b798eb70c46vandwalle int scoreB; 8192451dbcc4f9641df188326215b204b798eb70c46vandwalle 8202451dbcc4f9641df188326215b204b798eb70c46vandwalle // Retrieve the visibility 821f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 822f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 823f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 8242451dbcc4f9641df188326215b204b798eb70c46vandwalle // Error visibility wasn't set 825b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations NULL band status!"); 826f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 827f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 8282451dbcc4f9641df188326215b204b798eb70c46vandwalle 8292451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis, boost RSSI of current configuration 8302451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != currentConfiguration) { 8312451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(currentConfiguration)) { 83293a1fddee50a244d31036cddae6b7db6630fd93dvandwalle aRssiBoost = mWifiConfigStore.currentNetworkBoost; 8332451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(currentConfiguration)) { 83493a1fddee50a244d31036cddae6b7db6630fd93dvandwalle bRssiBoost = mWifiConfigStore.currentNetworkBoost; 8352451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8362451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8372451dbcc4f9641df188326215b204b798eb70c46vandwalle 8382451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 839b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI: " + a.configKey() 840f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " rssi=" + Integer.toString(astatus.rssi24) 841c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + "," + Integer.toString(astatus.rssi5) 8422451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(aRssiBoost) 843f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle + " " + b.configKey() + " rssi=" 844c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi24) + "," 845c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + Integer.toString(bstatus.rssi5) 8462451dbcc4f9641df188326215b204b798eb70c46vandwalle + " boost=" + Integer.toString(bRssiBoost) 8472451dbcc4f9641df188326215b204b798eb70c46vandwalle ); 848f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 8492451dbcc4f9641df188326215b204b798eb70c46vandwalle 850815788ba7838fc54310baed3deb9b95548e0ce69vandwalle order = compareWifiConfigurationsFromVisibility(a, aRssiBoost, b, bRssiBoost); 8512451dbcc4f9641df188326215b204b798eb70c46vandwalle 8522451dbcc4f9641df188326215b204b798eb70c46vandwalle // Normalize the order to [-50, +50] 8532451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 50) order = 50; 8542451dbcc4f9641df188326215b204b798eb70c46vandwalle else if (order < -50) order = -50; 8552451dbcc4f9641df188326215b204b798eb70c46vandwalle 8562451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 8572451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 8582451dbcc4f9641df188326215b204b798eb70c46vandwalle if (order > 0) { 8592451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; // Ascending 8602451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (order < 0) { 8612451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; // Descending 8622451dbcc4f9641df188326215b204b798eb70c46vandwalle } 863b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsRSSI " + a.configKey() 8642451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 8652451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 8662451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 8672451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 8682451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 8692451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 8702451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 8712451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 8722451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 8732451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + order); 8742451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8752451dbcc4f9641df188326215b204b798eb70c46vandwalle 876f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 877f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 878f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 879833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /** 880833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * b/18490330 only use scorer for untrusted networks 881833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle * 8822451dbcc4f9641df188326215b204b798eb70c46vandwalle int compareWifiConfigurationsWithScorer(WifiConfiguration a, WifiConfiguration b) { 8832451dbcc4f9641df188326215b204b798eb70c46vandwalle 88481c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean aIsActive = false; 88581c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean bIsActive = false; 8862451dbcc4f9641df188326215b204b798eb70c46vandwalle 8872451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply Hysteresis : boost RSSI of current configuration before 8882451dbcc4f9641df188326215b204b798eb70c46vandwalle // looking up the score 8892451dbcc4f9641df188326215b204b798eb70c46vandwalle if (null != mCurrentConfigurationKey) { 8902451dbcc4f9641df188326215b204b798eb70c46vandwalle if (a.configKey().equals(mCurrentConfigurationKey)) { 89181c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson aIsActive = true; 8922451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if (b.configKey().equals(mCurrentConfigurationKey)) { 89381c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson bIsActive = true; 8942451dbcc4f9641df188326215b204b798eb70c46vandwalle } 8952451dbcc4f9641df188326215b204b798eb70c46vandwalle } 896833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreA = getConfigNetworkScore(a, mScanResultAutoJoinAge, aIsActive); 897833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int scoreB = getConfigNetworkScore(b, mScanResultAutoJoinAge, bIsActive); 8982451dbcc4f9641df188326215b204b798eb70c46vandwalle 8992451dbcc4f9641df188326215b204b798eb70c46vandwalle // Both configurations need to have a score for the scorer to be used 9002451dbcc4f9641df188326215b204b798eb70c46vandwalle // ...and the scores need to be different:-) 9012451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA == WifiNetworkScoreCache.INVALID_NETWORK_SCORE 9022451dbcc4f9641df188326215b204b798eb70c46vandwalle || scoreB == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 903e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle if (VDBG) { 904b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer no-scores: " 905e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + a.configKey() 906e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " " 907e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + b.configKey()); 908e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle } 9092451dbcc4f9641df188326215b204b798eb70c46vandwalle return 0; 9102451dbcc4f9641df188326215b204b798eb70c46vandwalle } 9112451dbcc4f9641df188326215b204b798eb70c46vandwalle 9122451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 9132451dbcc4f9641df188326215b204b798eb70c46vandwalle String prefer = " = "; 9142451dbcc4f9641df188326215b204b798eb70c46vandwalle if (scoreA < scoreB) { 9152451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " < "; 9162451dbcc4f9641df188326215b204b798eb70c46vandwalle } if (scoreA > scoreB) { 9172451dbcc4f9641df188326215b204b798eb70c46vandwalle prefer = " > "; 9182451dbcc4f9641df188326215b204b798eb70c46vandwalle } 919b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurationsWithScorer " + a.configKey() 9202451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + a.visibility.rssi24 9212451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.rssi5 9222451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + a.visibility.num24 9232451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + a.visibility.num5 + ")" 924e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreA 9252451dbcc4f9641df188326215b204b798eb70c46vandwalle + prefer + b.configKey() 9262451dbcc4f9641df188326215b204b798eb70c46vandwalle + " rssi=(" + b.visibility.rssi24 9272451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.rssi5 9282451dbcc4f9641df188326215b204b798eb70c46vandwalle + ") num=(" + b.visibility.num24 9292451dbcc4f9641df188326215b204b798eb70c46vandwalle + "," + b.visibility.num5 + ")" 930e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle + " sc=" + scoreB 9312451dbcc4f9641df188326215b204b798eb70c46vandwalle + " -> " + Integer.toString(scoreB - scoreA)); 9322451dbcc4f9641df188326215b204b798eb70c46vandwalle } 933c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 9342451dbcc4f9641df188326215b204b798eb70c46vandwalle // If scoreA > scoreB, the comparison is descending hence the return value is negative 9352451dbcc4f9641df188326215b204b798eb70c46vandwalle return scoreB - scoreA; 9362451dbcc4f9641df188326215b204b798eb70c46vandwalle } 937833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 9382451dbcc4f9641df188326215b204b798eb70c46vandwalle 939f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 940f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 941f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 942f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 943453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 944453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 945453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 9462451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((a.linkedConfigurations.get(b.configKey(true)) != null) 9472451dbcc4f9641df188326215b204b798eb70c46vandwalle && (b.linkedConfigurations.get(a.configKey(true)) != null)) { 948f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 949f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 950f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 951f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 952f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 953f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 954b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + b.configKey() 955453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 956f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 957931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return 1; // b is of higher priority - ascending 958f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 959f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 960f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 961b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations ephemeral and prefers " + a.configKey() 962453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 963f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 964931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle return -1; // a is of higher priority - descending 965f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 966f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9672451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply RSSI, in the range [-5, +5] 9682451dbcc4f9641df188326215b204b798eb70c46vandwalle // after band adjustment, +n difference roughly corresponds to +10xn dBm 9692451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + compareWifiConfigurationsRSSI(a, b, mCurrentConfigurationKey); 970f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9712451dbcc4f9641df188326215b204b798eb70c46vandwalle // If the configurations are not linked, compare by user's choice, only a 9722451dbcc4f9641df188326215b204b798eb70c46vandwalle // very high RSSI difference can then override the choice 9732451dbcc4f9641df188326215b204b798eb70c46vandwalle if (!linked) { 9742451dbcc4f9641df188326215b204b798eb70c46vandwalle int choice; 975f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9762451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(a, b); 9772451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 978931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 9792451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - choice; 980f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 981b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + a.configKey() 982453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 983b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " due to user choice of " + choice 984b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order -> " + Integer.toString(order)); 985f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 986f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (a.visibility != null) { 987f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceBoost = choice; 988f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle a.visibility.lastChoiceConfig = b.configKey(); 989f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 9902451dbcc4f9641df188326215b204b798eb70c46vandwalle } 9912451dbcc4f9641df188326215b204b798eb70c46vandwalle 9922451dbcc4f9641df188326215b204b798eb70c46vandwalle choice = getConnectChoice(b, a); 9932451dbcc4f9641df188326215b204b798eb70c46vandwalle if (choice > 0) { 994931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 9952451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + choice; 9964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 997b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers " + b.configKey() + " over " 998b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + a.configKey() + " due to user choice of " + choice 999b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " order ->" + Integer.toString(order)); 1000f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1001f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle if (b.visibility != null) { 1002f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceBoost = choice; 1003f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle b.visibility.lastChoiceConfig = a.configKey(); 1004f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle } 1005f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1006f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1007ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 1008f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 1009931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // We don't know anything - pick the last seen i.e. K behavior 1010931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // we should do this only for recently picked configurations 1011f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 1012931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of higher priority - descending 10132451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 1014b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers -1 " + a.configKey() + " over " 1015453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 1016f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1017f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1018f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 1019f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 1020931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // a is of lower priority - ascending 10212451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 1022b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" compareWifiConfigurations prefers +1 " + b.configKey() + " over " 1023453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 1024f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 10252451dbcc4f9641df188326215b204b798eb70c46vandwalle order = 1; 1026f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1027f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1028f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1029f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 1030931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if (order > 0) { 1031f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 1032931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } else if (order < 0) { 1033f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 1034931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle } 1035f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 10362451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 1037b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("compareWifiConfigurations: " + a.configKey() + sorder 1038453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 1039f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1040f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1041f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 1042f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1043f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1044c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle boolean isBadCandidate(int rssi5, int rssi24) { 1045c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle return (rssi5 < -80 && rssi24 < -90); 1046c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1047c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 1048833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle /* 1049c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int compareWifiConfigurationsTop(WifiConfiguration a, WifiConfiguration b) { 1050c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int scorerOrder = compareWifiConfigurationsWithScorer(a, b); 1051c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle int order = compareWifiConfigurations(a, b); 1052c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 1053c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder * order < 0) { 1054b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (VDBG) { 1055b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" -> compareWifiConfigurationsTop: " + 1056b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle "scorer override " + scorerOrder + " " + order); 1057b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1058c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // For debugging purpose, remember that an override happened 1059c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // during that autojoin Attempt 1060c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = true; 1061c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle a.numScorerOverride++; 1062c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle b.numScorerOverride++; 1063c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 1064c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 1065c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle if (scorerOrder != 0) { 1066c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If the scorer came up with a result then use the scorer's result, else use 1067c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // the order provided by the base comparison function 1068c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle order = scorerOrder; 1069c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 1070c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle return order; 1071c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle } 1072833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle */ 1073c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle 10749f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle public int rssiBoostFrom5GHzRssi(int rssi, String dbg) { 10750eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!mWifiConfigStore.enable5GHzPreference) { 10760eebae7334d6129f7ca1344e4b20199794994358vandwalle return 0; 10770eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1078e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 107977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist > mWifiConfigStore.bandPreferenceBoostThreshold5.get()) { 1080e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 2 dB for each point 1081e67ec726c07410073575473c0f50dc737629f5davandwalle // Start boosting at -65 1082e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 20 if above -55 1083e67ec726c07410073575473c0f50dc737629f5davandwalle // Boost by 40 if abore -45 10840eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferenceBoostFactor5 108577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist *(rssi - mWifiConfigStore.bandPreferenceBoostThreshold5.get()); 1086e67ec726c07410073575473c0f50dc737629f5davandwalle if (boost > 50) { 1087815788ba7838fc54310baed3deb9b95548e0ce69vandwalle // 50 dB boost allows jumping from 2.4 to 5GHz 1088e67ec726c07410073575473c0f50dc737629f5davandwalle // consistently 1089e67ec726c07410073575473c0f50dc737629f5davandwalle boost = 50; 1090e67ec726c07410073575473c0f50dc737629f5davandwalle } 10919f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle if (VDBG && dbg != null) { 1092f57f8918b8c5872ff4bb141fa9e407bec8442e8dvandwalle logDbg(" " + dbg + ": rssi5 " + rssi + " 5GHz-boost " + boost); 10939f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1094e67ec726c07410073575473c0f50dc737629f5davandwalle return boost; 1095e67ec726c07410073575473c0f50dc737629f5davandwalle } 1096e67ec726c07410073575473c0f50dc737629f5davandwalle 1097e67ec726c07410073575473c0f50dc737629f5davandwalle if (rssi 109877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist < mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 10990eebae7334d6129f7ca1344e4b20199794994358vandwalle // penalize if < -75 11000eebae7334d6129f7ca1344e4b20199794994358vandwalle int boost = mWifiConfigStore.bandPreferencePenaltyFactor5 110177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist *(rssi - mWifiConfigStore.bandPreferencePenaltyThreshold5.get()); 11020eebae7334d6129f7ca1344e4b20199794994358vandwalle return boost; 1103e67ec726c07410073575473c0f50dc737629f5davandwalle } 1104e67ec726c07410073575473c0f50dc737629f5davandwalle return 0; 1105e67ec726c07410073575473c0f50dc737629f5davandwalle } 1106c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle /** 1107e67ec726c07410073575473c0f50dc737629f5davandwalle * attemptRoam() function implements the core of the same SSID switching algorithm 1108e67ec726c07410073575473c0f50dc737629f5davandwalle * 1109e67ec726c07410073575473c0f50dc737629f5davandwalle * Run thru all recent scan result of a WifiConfiguration and select the 1110e67ec726c07410073575473c0f50dc737629f5davandwalle * best one. 1111c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle */ 1112e67ec726c07410073575473c0f50dc737629f5davandwalle public ScanResult attemptRoam(ScanResult a, 1113e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration current, int age, String currentBSSID) { 1114b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current == null) { 1115b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1116b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam not associated"); 1117b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1118e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 11194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1120b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current.scanResultCache == null) { 1121b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1122b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam no scan cache"); 1123b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1124e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 11254dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1126b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle if (current.scanResultCache.size() > 6) { 1127b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 1128c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam scan cache size " 1129c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + current.scanResultCache.size() + " --> bail"); 1130b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1131931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Implement same SSID roaming only for configurations 1132c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // that have less than 4 BSSIDs 1133e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 11344dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1135b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 11362f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (current.BSSID != null && !current.BSSID.equals("any")) { 1137b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 11382f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("attemptRoam() BSSID is set " 11392f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + current.BSSID + " -> bail"); 1140b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1141e67ec726c07410073575473c0f50dc737629f5davandwalle return a; 11424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1144931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Determine which BSSID we want to associate to, taking account 1145c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // relative strength of 5 and 2.4 GHz BSSIDs 11462451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 11474dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 114897b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle for (ScanResult b : current.scanResultCache.values()) { 114997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost5 = 0; 115097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost5 = 0; 115197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int bRssiBoost = 0; 115297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle int aRssiBoost = 0; 1153931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle if ((b.seen == 0) || (b.BSSID == null) 11540d616ef3bf635dff8722e064c0be842676390ed8vandwalle || ((nowMs - b.seen) > age) 1155e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.autoJoinStatus != ScanResult.ENABLED 1156e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle || b.numIpConfigFailures > 8) { 11574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 11583a2a3d226881cce8a4e511302231d843b0def303vandwalle } 11594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1160931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Pick first one 11614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (a == null) { 11624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle a = b; 11634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 11644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1166e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (b.numIpConfigFailures < (a.numIpConfigFailures - 1)) { 1167e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle // Prefer a BSSID that doesn't have less number of Ip config failures 1168e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptRoam: " 1169e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + b.BSSID + " rssi=" + b.level + " ipfail=" +b.numIpConfigFailures 1170e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + b.frequency 1171e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " > " 1172e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + a.BSSID + " rssi=" + a.level + " ipfail=" +a.numIpConfigFailures 1173e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " freq=" + a.frequency); 1174e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle a = b; 1175e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle continue; 1176e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1177e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle 11782451dbcc4f9641df188326215b204b798eb70c46vandwalle // Apply hysteresis: we favor the currentBSSID by giving it a boost 11797806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(b.BSSID)) { 1180931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 118177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (b.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 11820eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1183c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 11840eebae7334d6129f7ca1344e4b20199794994358vandwalle bRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1185c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 11864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11877806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null && currentBSSID.equals(a.BSSID)) { 118877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (a.level <= mWifiConfigStore.bandPreferencePenaltyThreshold5.get()) { 1189931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reduce the benefit of hysteresis if RSSI <= -75 11900eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisLow; 1191c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 11920eebae7334d6129f7ca1344e4b20199794994358vandwalle aRssiBoost = mWifiConfigStore.associatedHysteresisHigh; 1193c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 11944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 11952451dbcc4f9641df188326215b204b798eb70c46vandwalle 119697b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve 11972451dbcc4f9641df188326215b204b798eb70c46vandwalle // Boost the BSSID if it is on 5GHz, above a threshold 11982451dbcc4f9641df188326215b204b798eb70c46vandwalle // But penalize it if it is on 5GHz and below threshold 119997b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // 120097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // With he current threshold values, 5GHz network with RSSI above -55 120197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // Are given a boost of 30DB which is enough to overcome the current BSSID 120297b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle // hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases 12039f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // 12049f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // The "current BSSID" Boost must be added to the BSSID's level so as to introduce\ 12059f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle // soem amount of hysteresis 1206e67ec726c07410073575473c0f50dc737629f5davandwalle if (b.is5GHz()) { 12079f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle bRssiBoost5 = rssiBoostFrom5GHzRssi(b.level + bRssiBoost, b.BSSID); 12084dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1209e67ec726c07410073575473c0f50dc737629f5davandwalle if (a.is5GHz()) { 12109f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle aRssiBoost5 = rssiBoostFrom5GHzRssi(a.level + aRssiBoost, a.BSSID); 12114dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 12124dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 12134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 1214c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle String comp = " < "; 1215c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1216c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle comp = " > "; 1217c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 12184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptRoam: " 1219c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost) 122097b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency 122197b9c4fef6e372d1f19b333c7a67ff27ef80baf0vandwalle + comp 1222c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost) 1223c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency); 1224c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 1225c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle 12262451dbcc4f9641df188326215b204b798eb70c46vandwalle // Compare the RSSIs after applying the hysteresis boost and the 5GHz 12272451dbcc4f9641df188326215b204b798eb70c46vandwalle // boost if applicable 1228c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 1229931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // b is the better BSSID 1230c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle a = b; 12314dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 12324dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 12333a2a3d226881cce8a4e511302231d843b0def303vandwalle if (a != null) { 12343a2a3d226881cce8a4e511302231d843b0def303vandwalle if (VDBG) { 12357806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle StringBuilder sb = new StringBuilder(); 1236e67ec726c07410073575473c0f50dc737629f5davandwalle sb.append("attemptRoam: " + current.configKey() + 1237e67ec726c07410073575473c0f50dc737629f5davandwalle " Found " + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency); 12387806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentBSSID != null) { 12397806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append(" Current: " + currentBSSID); 12407806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 12417806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle sb.append("\n"); 12427806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle logDbg(sb.toString()); 12433a2a3d226881cce8a4e511302231d843b0def303vandwalle } 12444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 12453a2a3d226881cce8a4e511302231d843b0def303vandwalle return a; 12464dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 12474dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1248931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 12492451dbcc4f9641df188326215b204b798eb70c46vandwalle * getNetworkScore() 12502451dbcc4f9641df188326215b204b798eb70c46vandwalle * 12512451dbcc4f9641df188326215b204b798eb70c46vandwalle * if scorer is present, get the network score of a WifiConfiguration 12522451dbcc4f9641df188326215b204b798eb70c46vandwalle * 12532451dbcc4f9641df188326215b204b798eb70c46vandwalle * Note: this should be merge with setVisibility 12542451dbcc4f9641df188326215b204b798eb70c46vandwalle * 12552451dbcc4f9641df188326215b204b798eb70c46vandwalle * @param config 12562451dbcc4f9641df188326215b204b798eb70c46vandwalle * @return score 12572451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 125881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int getConfigNetworkScore(WifiConfiguration config, int age, boolean isActive) { 12592451dbcc4f9641df188326215b204b798eb70c46vandwalle 12602451dbcc4f9641df188326215b204b798eb70c46vandwalle if (mNetworkScoreCache == null) { 1261e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1262b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1263e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scorer, hence no scores"); 1264e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 12651db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 12661db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 12671db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (config.scanResultCache == null) { 1268e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1269b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1270e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no scan cache"); 1271e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 12721db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 12732451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12742451dbcc4f9641df188326215b204b798eb70c46vandwalle 12752451dbcc4f9641df188326215b204b798eb70c46vandwalle // Get current date 12762451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 12772451dbcc4f9641df188326215b204b798eb70c46vandwalle 12781db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle int startScore = -10000; 12791db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle 12802451dbcc4f9641df188326215b204b798eb70c46vandwalle // Run thru all cached scan results 12811db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle for (ScanResult result : config.scanResultCache.values()) { 12822451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((nowMs - result.seen) < age) { 128381c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int sc = mNetworkScoreCache.getNetworkScore(result, isActive); 12841db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (sc > startScore) { 12851db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = sc; 12862451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12872451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12882451dbcc4f9641df188326215b204b798eb70c46vandwalle } 12891db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle if (startScore == -10000) { 12901db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle startScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE; 12911db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle } 1292e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (VDBG) { 1293e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle if (startScore == WifiNetworkScoreCache.INVALID_NETWORK_SCORE) { 1294b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 1295e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " -> no available score"); 1296e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } else { 1297b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg(" getConfigNetworkScore for " + config.configKey() 129881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson + " isActive=" + isActive 1299e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle + " score = " + Integer.toString(startScore)); 1300e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1301e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle } 1302e6574ec7b6b2e7a678da7f77bdaaf31463852b2fvandwalle 13031db63db890fcb9051f402fdfd449eb0b80e2053cvandwalle return startScore; 13042451dbcc4f9641df188326215b204b798eb70c46vandwalle } 13052451dbcc4f9641df188326215b204b798eb70c46vandwalle 13062451dbcc4f9641df188326215b204b798eb70c46vandwalle /** 13078639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson * Set whether connections to untrusted connections are allowed. 13088639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson */ 13098639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson void setAllowUntrustedConnections(boolean allow) { 13108639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson boolean changed = mAllowUntrustedConnections != allow; 13118639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson mAllowUntrustedConnections = allow; 13128639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (changed) { 1313005c1ef113192f898499a407dd266393a8d6b076vandwalle // Trigger a scan so as to reattempt autojoin 1314005c1ef113192f898499a407dd266393a8d6b076vandwalle mWifiStateMachine.startScanForUntrustedSettingChange(); 13158639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 13168639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 13178639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 13188639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson private boolean isOpenNetwork(ScanResult result) { 13198639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson return !result.capabilities.contains("WEP") && 13208639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("PSK") && 13218639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !result.capabilities.contains("EAP"); 13228639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson } 13238639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 132416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson private boolean haveRecentlySeenScoredBssid(WifiConfiguration config) { 132516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long ephemeralOutOfRangeTimeoutMs = Settings.Global.getLong( 132616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson mContext.getContentResolver(), 132716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson Settings.Global.WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS, 132816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS); 132916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 133016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Check whether the currently selected network has a score curve. If 133116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // ephemeralOutOfRangeTimeoutMs is <= 0, then this is all we check, and we stop here. 133216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // Otherwise, we stop here if the currently selected network has a score. If it doesn't, we 133316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // keep going - it could be that another BSSID is in range (has been seen recently) which 133416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson // has a score, even if the one we're immediately connected to doesn't. 133516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson ScanResult currentScanResult = mWifiStateMachine.getCurrentScanResult(); 133616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson boolean currentNetworkHasScoreCurve = mNetworkScoreCache.hasScoreCurve(currentScanResult); 133716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (ephemeralOutOfRangeTimeoutMs <= 0 || currentNetworkHasScoreCurve) { 133816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 133916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (currentNetworkHasScoreCurve) { 134016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has a score curve, keeping network: " 134116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson + currentScanResult); 134216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } else { 134316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Current network has no score curve, giving up: " + config.SSID); 134416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 134516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 134616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return currentNetworkHasScoreCurve; 134716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 134816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 134916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (config.scanResultCache == null || config.scanResultCache.isEmpty()) { 135016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 135116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 135216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 135316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson long currentTimeMs = System.currentTimeMillis(); 135416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson for (ScanResult result : config.scanResultCache.values()) { 135516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (currentTimeMs > result.seen 135616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson && currentTimeMs - result.seen < ephemeralOutOfRangeTimeoutMs 135716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson && mNetworkScoreCache.hasScoreCurve(result)) { 135816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 135916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("Found scored BSSID, keeping network: " + result.BSSID); 136016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 136116fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return true; 136216fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 136316fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 136416fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 136516fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson if (DBG) { 136616fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson logDbg("No recently scored BSSID found, giving up connection: " + config.SSID); 136716fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 136816fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson return false; 136916fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson } 137016fdf07021858fd116d96a5fb00ddb3c166d5ae6Jeff Davidson 137177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // After WifiStateMachine ask the supplicant to associate or reconnect 137277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // we might still obtain scan results from supplicant 137377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // however the supplicant state in the mWifiInfo and supplicant state tracker 137477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // are updated when we get the supplicant state change message which can be 137577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // processed after the SCAN_RESULT message, so at this point the framework doesn't 137677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // know that supplicant is ASSOCIATING. 137777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // A good fix for this race condition would be for the WifiStateMachine to add 137877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // a new transient state where it expects to get the supplicant message indicating 137977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // that it started the association process and within which critical operations 138077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // like autojoin should be deleted. 138177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 138277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // This transient state would remove the need for the roam Wathchdog which 138377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // basically does that. 138477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 138577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // At the moment, we just query the supplicant state synchronously with the 138677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // mWifiNative.status() command, which allow us to know that 138777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // supplicant has started association process, even though we didnt yet get the 138877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // SUPPLICANT_STATE_CHANGE message. 138977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 139077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final List<String> ASSOC_STATES = Arrays.asList( 139177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "ASSOCIATING", 139277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "ASSOCIATED", 139377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "FOUR_WAY_HANDSHAKE", 139477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "GROUP_KEY_HANDSHAKE"); 139577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 139677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private int getNetID(String wpaStatus) { 139777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (VDBG) { 139877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() status=" + wpaStatus); 139977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 140077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 140177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist try { 140277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int id = WifiConfiguration.INVALID_NETWORK_ID; 140377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String state = null; 140477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist BufferedReader br = new BufferedReader(new StringReader(wpaStatus)); 140577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String line; 140677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist while((line = br.readLine()) != null) { 140777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int split = line.indexOf('='); 140877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (split < 0) { 140977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist continue; 141077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 141177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 141277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String name = line.substring(0, split); 141377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (name.equals("id")) { 141477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist try { 141577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist id = Integer.parseInt(line.substring(split+1)); 141677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (state != null) { 141777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist break; 141877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 141977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 142077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist catch (NumberFormatException nfe) { 142177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Log.d("HS2J", "NFE on '" + line + "'"); 142277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; 142377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 142477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 142577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist else if (name.equals("wpa_state")) { 142677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist state = line.substring(split+1); 142777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Log.d("HS2J", "State: '" + line + "'"); 142877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (ASSOC_STATES.contains(state)) { 142977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; 143077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 143177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist else if (id >= 0) { 143277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist break; 143377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 143477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 143577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 143677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return id; 143777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 143877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist catch (IOException ioe) { 143977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return WifiConfiguration.INVALID_NETWORK_ID; // Won't happen 144077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 144177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 144277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 144377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private boolean setCurrentConfigurationKey(WifiConfiguration currentConfig, 144477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int supplicantNetId) { 144577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (currentConfig != null) { 144677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (supplicantNetId != currentConfig.networkId 144777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // https://b.corp.google.com/issue?id=16484607 144877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // mark this condition as an error only if the mismatched networkId are valid 144977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && supplicantNetId != WifiConfiguration.INVALID_NETWORK_ID 145077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && currentConfig.networkId != WifiConfiguration.INVALID_NETWORK_ID) { 145177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 145277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(supplicantNetId) + " WifiStateMachine=" 145377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(currentConfig.networkId)); 145477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiStateMachine.disconnectCommand(); 145577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 145677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else if (currentConfig.ephemeral && (!mAllowUntrustedConnections || 145777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist !haveRecentlySeenScoredBssid(currentConfig))) { 145877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // The current connection is untrusted (the framework added it), but we're either 145977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // no longer allowed to connect to such networks, the score has been nullified 146077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // since we connected, or the scored BSSID has gone out of range. 146177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Drop the current connection and perform the rest of autojoin. 146277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network"); 146377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiStateMachine.disconnectCommand(Process.WIFI_UID, 146477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAllowUntrustedConnections ? 1 : 0); 146577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 146677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 146777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCurrentConfigurationKey = currentConfig.configKey(); 146877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return true; 146977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 147077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 147177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // If not invalid, then maybe in the process of associating, skip this attempt 147277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return supplicantNetId == WifiConfiguration.INVALID_NETWORK_ID; 147377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 147477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 147577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 147677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private void updateBlackListStatus(WifiConfiguration config, long now) { 147777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Wait for 5 minutes before reenabling config that have known, 147877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // repeated connection or DHCP failures 147977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE 148077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || config.disableReason 148177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist == WifiConfiguration.DISABLED_ASSOCIATION_REJECT 148277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || config.disableReason 148377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist == WifiConfiguration.DISABLED_AUTH_FAILURE) { 148477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.blackListTimestamp == 0 148577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist || (config.blackListTimestamp > now)) { 148677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Sanitize the timestamp 148777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.blackListTimestamp = now; 148877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 148977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if ((now - config.blackListTimestamp) > 149077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.wifiConfigBlacklistMinTimeMilli) { 149177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Re-enable the WifiConfiguration 149277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.status = WifiConfiguration.Status.ENABLED; 149377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 149477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Reset the blacklist condition 149577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numConnectionFailures = 0; 149677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numIpConfigFailures = 0; 149777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.numAuthFailures = 0; 149877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 149977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 150077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist config.dirty = true; 150177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 150277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (VDBG) { 150377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist long delay = mWifiConfigStore.wifiConfigBlacklistMinTimeMilli 150477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist - (now - config.blackListTimestamp); 150577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptautoJoin " + config.configKey() 150677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + " dont unblacklist yet, waiting for " 150777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + delay + " ms"); 150877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 150977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 151077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 151177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // Avoid networks disabled because of AUTH failure altogether 151277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (DBG) { 151377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg("attemptAutoJoin skip candidate due to auto join status " 151477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + Integer.toString(config.autoJoinStatus) + " key " 151577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + config.configKey(true) 151677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist + " reason " + config.disableReason); 151777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 151877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 151977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 152077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underSoftThreshold(WifiConfiguration config) { 152177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Soft.get() 152277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Soft.get(); 152377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 152477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 152577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underHardThreshold(WifiConfiguration config) { 152677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < mWifiConfigStore.thresholdUnblacklistThreshold24Hard.get() 152777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist && config.visibility.rssi5 < mWifiConfigStore.thresholdUnblacklistThreshold5Hard.get(); 152877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 152977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 153077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean underThreshold(WifiConfiguration config, int rssi24, int rssi5) { 153177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return config.visibility.rssi24 < rssi24 && config.visibility.rssi5 < rssi5; 153277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 153377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 15348639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson /** 1535931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * attemptAutoJoin() function implements the core of the a network switching algorithm 153668fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle * Return false if no acceptable networks were found. 1537931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 153868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean attemptAutoJoin() { 153968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle boolean found = false; 1540c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle didOverride = false; 15411ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = false; 1542b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkSwitchType = AUTO_JOIN_IDLE; 15434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 15448242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle long now = System.currentTimeMillis(); 15458242cc81341c80ab5bc057ffdad99a3a1d95be5cvandwalle 15468c9088d11880553458f09377cc60d6eb7e66747bvandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 15478c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1548931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reset the currentConfiguration Key, and set it only if WifiStateMachine and 1549453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 1550453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 1551453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 1552453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1553f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 1554f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1555931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Obtain the subset of recently seen networks 1556833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle List<WifiConfiguration> list = 1557833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.getRecentConfiguredNetworks(mScanResultAutoJoinAge, false); 1558f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 15592f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) logDbg("attemptAutoJoin nothing known=" + 15602f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle mWifiConfigStore.getconfiguredNetworkSize()); 156168fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return false; 1562f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1563f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1564931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Find the currently connected network: ask the supplicant directly 156577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 156677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int supplicantNetId = getNetID(mWifiNative.status(true)); 156777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1568ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 15697806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle String conf = ""; 1570b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String last = ""; 15717806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle if (currentConfiguration != null) { 1572e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle conf = " current=" + currentConfiguration.configKey(); 1573b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1574b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (lastSelectedConfiguration != null) { 15752f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle last = " last=" + lastSelectedConfiguration; 15767806f8c800754da0f76d7a0c1a6a590381dac7a8vandwalle } 1577ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 1578b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + conf + last 1579b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " ---> suppNetId=" + Integer.toString(supplicantNetId)); 1580ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1581f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 158277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (!setCurrentConfigurationKey(currentConfiguration, supplicantNetId)) { 158377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 1584453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 1585453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 1586b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int currentNetId = -1; 1587b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentConfiguration != null) { 1588931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If we are associated to a configuration, it will 1589b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // be compared thru the compareNetwork function 1590b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle currentNetId = currentConfiguration.networkId; 1591b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 1592b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle 1593931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1594931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Run thru all visible configurations without looking at the one we 1595c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle * are currently associated to 15964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * select Best Network candidate from known WifiConfigurations 1597931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1598f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 1599e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 1600b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle continue; 1601e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 1602e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 160377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.autoJoinStatus >= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) { 160477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist updateBlackListStatus(config, now); 1605f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1606f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1607f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1608931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to un-blacklist based on elapsed time 160927355a942653264388e909a4276196ee63e57811vandwalle if (config.blackListTimestamp > 0) { 161027355a942653264388e909a4276196ee63e57811vandwalle if (now < config.blackListTimestamp) { 1611931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1612931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * looks like there was a change in the system clock since we black listed, and 1613931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * timestamp is not meaningful anymore, hence lose it. 1614931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * this event should be rare enough so that we still want to lose the black list 16152451dbcc4f9641df188326215b204b798eb70c46vandwalle */ 161627355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 161727355a942653264388e909a4276196ee63e57811vandwalle } else { 16184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now - config.blackListTimestamp) > loseBlackListHardMilli) { 1619931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Reenable it after 18 hours, i.e. next day 162027355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 16214dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) { 1622931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Lose blacklisting due to bad link 162327355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 8); 162427355a942653264388e909a4276196ee63e57811vandwalle } 162527355a942653264388e909a4276196ee63e57811vandwalle } 162627355a942653264388e909a4276196ee63e57811vandwalle } 162727355a942653264388e909a4276196ee63e57811vandwalle 162877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // !!! JNo: This ought to be checked here rather than below... 162977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (config.visibility == null) { 163077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist continue; 163177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 163277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1633931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Try to unblacklist based on good visibility 163477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (underSoftThreshold(config)) { 163577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin do not unblacklist due to low visibility ", config); 163677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else if (underHardThreshold(config)) { 1637931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // If the network is simply temporary disabled, don't allow reconnect until 1638931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // RSSI becomes good enough 163927355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 1); 164077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin good candidate seen, bumped soft -> status=", config); 164127355a942653264388e909a4276196ee63e57811vandwalle } else { 1642c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 3); 164377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin good candidate seen, bumped hard -> status=", config); 164427355a942653264388e909a4276196ee63e57811vandwalle } 164527355a942653264388e909a4276196ee63e57811vandwalle 164627355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 164727355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 1648931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Network is blacklisted, skip 164977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin skip blacklisted -> status=", config); 165027355a942653264388e909a4276196ee63e57811vandwalle continue; 165127355a942653264388e909a4276196ee63e57811vandwalle } 1652f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 1653ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 165421bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("attemptAutoJoin skip current candidate " 165521bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle + Integer.toString(currentNetId) 1656ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 1657ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1658f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1659f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1660f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 16610eebae7334d6129f7ca1344e4b20199794994358vandwalle boolean isLastSelected = false; 16620eebae7334d6129f7ca1344e4b20199794994358vandwalle if (lastSelectedConfiguration != null && 16630eebae7334d6129f7ca1344e4b20199794994358vandwalle config.configKey().equals(lastSelectedConfiguration)) { 16640eebae7334d6129f7ca1344e4b20199794994358vandwalle isLastSelected = true; 16650eebae7334d6129f7ca1344e4b20199794994358vandwalle } 16660eebae7334d6129f7ca1344e4b20199794994358vandwalle 16671ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount; 166877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (underThreshold(config, 166977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.thresholdInitialAutoJoinAttemptMin24RSSI.get() - boost, 167077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI.get() - boost)) { 167177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 167277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDenial("attemptAutoJoin skip due to low visibility -> status=", config); 16730eebae7334d6129f7ca1344e4b20199794994358vandwalle 1674c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // Don't try to autojoin a network that is too far but 1675c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // If that configuration is a user's choice however, try anyway 16760eebae7334d6129f7ca1344e4b20199794994358vandwalle if (!isLastSelected) { 16770eebae7334d6129f7ca1344e4b20199794994358vandwalle config.autoJoinBailedDueToLowRssi = true; 16781ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle didBailDueToWeakRssi = true; 16798c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 16800eebae7334d6129f7ca1344e4b20199794994358vandwalle } else { 16810eebae7334d6129f7ca1344e4b20199794994358vandwalle // Next time, try to be a bit more aggressive in auto-joining 16820eebae7334d6129f7ca1344e4b20199794994358vandwalle if (config.autoJoinUseAggressiveJoinAttemptThreshold 1683dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle < WifiConfiguration.MAX_INITIAL_AUTO_JOIN_RSSI_BOOST 1684dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle && config.autoJoinBailedDueToLowRssi) { 1685dd0c558776fcfba3f754bb0cd6533f2c9c23ec1evandwalle config.autoJoinUseAggressiveJoinAttemptThreshold += 4; 16864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 16878c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 16880eebae7334d6129f7ca1344e4b20199794994358vandwalle } 1689d30127db46224e45554f8964209221bba8ad41d9vandwalle if (config.numNoInternetAccessReports > 0 1690d30127db46224e45554f8964209221bba8ad41d9vandwalle && !isLastSelected 1691d30127db46224e45554f8964209221bba8ad41d9vandwalle && !config.validatedInternetAccess) { 1692d30127db46224e45554f8964209221bba8ad41d9vandwalle // Avoid autoJoining this network because last time we used it, it didn't 1693d30127db46224e45554f8964209221bba8ad41d9vandwalle // have internet access, and we never manage to validate internet access on this 1694d30127db46224e45554f8964209221bba8ad41d9vandwalle // network configuration 16950eebae7334d6129f7ca1344e4b20199794994358vandwalle if (DBG) { 1696d30127db46224e45554f8964209221bba8ad41d9vandwalle logDbg("attemptAutoJoin skip candidate due to no InternetAccess " 1697d30127db46224e45554f8964209221bba8ad41d9vandwalle + config.configKey(true) 1698d30127db46224e45554f8964209221bba8ad41d9vandwalle + " num reports " + config.numNoInternetAccessReports); 16999f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 17000eebae7334d6129f7ca1344e4b20199794994358vandwalle continue; 17018c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 17028c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1703ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1704e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle String cur = ""; 1705e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle if (candidate != null) { 1706e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle cur = " current candidate " + candidate.configKey(); 1707e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle } 1708e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle logDbg("attemptAutoJoin trying id=" 1709c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Integer.toString(config.networkId) + " " 1710b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + config.configKey(true) 1711e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + " status=" + config.autoJoinStatus 1712e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle + cur); 1713ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1714f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1715f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 1716f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1717f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1718f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1719453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 17204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " with " + config.configKey()); 1721f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1722833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle int order = compareWifiConfigurations(candidate, config); 17232451dbcc4f9641df188326215b204b798eb70c46vandwalle 17242451dbcc4f9641df188326215b204b798eb70c46vandwalle // The lastSelectedConfiguration is the configuration the user has manually selected 1725c290d8dff6172d5fde7b9dfd74d3a20785dab246vandwalle // thru WifiPicker, or that a 3rd party app asked us to connect to via the 17262451dbcc4f9641df188326215b204b798eb70c46vandwalle // enableNetwork with disableOthers=true WifiManager API 17272451dbcc4f9641df188326215b204b798eb70c46vandwalle // As this is a direct user choice, we strongly prefer this configuration, 17282451dbcc4f9641df188326215b204b798eb70c46vandwalle // hence give +/-100 17292451dbcc4f9641df188326215b204b798eb70c46vandwalle if ((lastSelectedConfiguration != null) 17302451dbcc4f9641df188326215b204b798eb70c46vandwalle && candidate.configKey().equals(lastSelectedConfiguration)) { 17312451dbcc4f9641df188326215b204b798eb70c46vandwalle // candidate is the last selected configuration, 17322451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 17332451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 17342451dbcc4f9641df188326215b204b798eb70c46vandwalle // by reducing order by -100 17352451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order - 100; 17362451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 17372f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers -100 " + candidate.configKey() 17382451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + config.configKey() 17392451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 17402451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 17412451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17422451dbcc4f9641df188326215b204b798eb70c46vandwalle } else if ((lastSelectedConfiguration != null) 17432451dbcc4f9641df188326215b204b798eb70c46vandwalle && config.configKey().equals(lastSelectedConfiguration)) { 17442451dbcc4f9641df188326215b204b798eb70c46vandwalle // config is the last selected configuration, 17452451dbcc4f9641df188326215b204b798eb70c46vandwalle // so keep it above connect choices (+/-60) and 17462451dbcc4f9641df188326215b204b798eb70c46vandwalle // above RSSI/scorer based selection of linked configuration (+/- 50) 17472451dbcc4f9641df188326215b204b798eb70c46vandwalle // by increasing order by +100 17482451dbcc4f9641df188326215b204b798eb70c46vandwalle order = order + 100; 17492451dbcc4f9641df188326215b204b798eb70c46vandwalle if (VDBG) { 17502f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg(" ...and prefers +100 " + config.configKey() 17512451dbcc4f9641df188326215b204b798eb70c46vandwalle + " over " + candidate.configKey() 17522451dbcc4f9641df188326215b204b798eb70c46vandwalle + " because it is the last selected -> " 17532451dbcc4f9641df188326215b204b798eb70c46vandwalle + Integer.toString(order)); 17542451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17552451dbcc4f9641df188326215b204b798eb70c46vandwalle } 17562451dbcc4f9641df188326215b204b798eb70c46vandwalle 1757f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 1758931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Ascending : candidate < config 1759f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1760f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1761f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1762f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1763f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 17642451dbcc4f9641df188326215b204b798eb70c46vandwalle // Now, go thru scan result to try finding a better untrusted network 1765833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if (mNetworkScoreCache != null && mAllowUntrustedConnections) { 1766f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 1767f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 1768f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 1769f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 1770f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 1771f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1772f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1773931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Get current date 17742451dbcc4f9641df188326215b204b798eb70c46vandwalle long nowMs = System.currentTimeMillis(); 1775c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle int currentScore = -10000; 1776c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // The untrusted network with highest score 1777c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle ScanResult untrustedCandidate = null; 17782451dbcc4f9641df188326215b204b798eb70c46vandwalle // Look for untrusted scored network only if the current candidate is bad 1779c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (isBadCandidate(rssi24, rssi5)) { 1780f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (ScanResult result : scanResultCache.values()) { 1781c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We look only at untrusted networks with a valid SSID 1782c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // A trusted result would have been looked at thru it's Wificonfiguration 17838639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson if (TextUtils.isEmpty(result.SSID) || !result.untrusted || 17848639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson !isOpenNetwork(result)) { 1785c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle continue; 1786c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 17872ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains 17882ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle ("\"" + result.SSID + "\"")) { 17892ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle // SSID had been Forgotten by user, then don't score it 17902ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle continue; 17912ce99b40c36ed0352b31aa85d5f9383d5f0506f5vandwalle } 1792833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle if ((nowMs - result.seen) < mScanResultAutoJoinAge) { 1793c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Increment usage count for the network 1794c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle mWifiConnectionStatistics.incrementOrAddUntrusted(result.SSID, 0, 1); 1795c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle 179681c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson boolean isActiveNetwork = lastUntrustedBSSID != null 179781c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson && result.BSSID.equals(lastUntrustedBSSID); 179881c9ea6c343bc7f8d87095237e59844a974d0b70Jeff Davidson int score = mNetworkScoreCache.getNetworkScore(result, isActiveNetwork); 1799c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (score != WifiNetworkScoreCache.INVALID_NETWORK_SCORE 1800c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle && score > currentScore) { 1801c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Highest score: Select this candidate 1802c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle currentScore = score; 1803c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle untrustedCandidate = result; 1804c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (VDBG) { 1805c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle logDbg("AutoJoinController: found untrusted candidate " 1806c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + result.SSID 1807c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " RSSI=" + result.level 1808c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " freq=" + result.frequency 1809c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle + " score=" + score); 1810c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1811f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1812f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1813f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1814f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1815c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (untrustedCandidate != null) { 1816c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle if (lastUntrustedBSSID == null 1817c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle || !untrustedCandidate.SSID.equals(lastUntrustedBSSID)) { 1818c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // We found a new candidate that we are going to connect to, then 1819c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // increase its connection count 18208c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle mWifiConnectionStatistics. 18218c0a54e9b0d3713cab52d06ad8fd7f3a1b6f73a8vandwalle incrementOrAddUntrusted(untrustedCandidate.SSID, 1, 0); 1822c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle // Remember which SSID we are connecting to 1823c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle lastUntrustedBSSID = untrustedCandidate.SSID; 1824c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 18258639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson 18268639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // At this point, we have an untrusted network candidate. 18278639f6266cb70bf92d1561af43ac2d7b2b97298eJeff Davidson // Create the new ephemeral configuration and see if we should switch over 1828833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate = 1829833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle mWifiConfigStore.wifiConfigurationFromScanResult(untrustedCandidate); 1830833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.allowedKeyManagement.set(KeyMgmt.NONE); 1831833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle candidate.ephemeral = true; 1832c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1833c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle } 1834b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 18351ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle long lastUnwanted = 18361ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle System.currentTimeMillis() 18371ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle - mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp; 18381ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (candidate == null 18391ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && lastSelectedConfiguration == null 18401ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && currentConfiguration == null 18411ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && didBailDueToWeakRssi 18421ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle && (mWifiConfigStore.lastUnwantedNetworkDisconnectTimestamp == 0 18431ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle || lastUnwanted > (1000 * 60 * 60 * 24 * 7)) 18441ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle ) { 18451ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // We are bailing out of autojoin although we are seeing a weak configuration, and 18461ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we didn't find another valid candidate 18471ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - we are not connected 18481ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - without a user network selection choice 18491ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // - ConnectivityService has not triggered an unwanted network disconnect 18501ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // on this device for a week (hence most likely there is no SIM card or cellular) 18511ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // If all those conditions are met, then boost the RSSI of the weak networks 18521ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle // that we are seeing so as we will eventually pick one 18531ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount < 10) 18541ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount += 1; 18551ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } else { 18561ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle if (weakRssiBailCount > 0) 18571ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle weakRssiBailCount -= 1; 18581ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle } 18591ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle 1860931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1861931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * If candidate is found, check the state of the connection so as 1862931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * to decide if we should be acting on this candidate and switching over 1863931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 1864e0aa0a004d161173992a0e9af1b431fae91f4a71vandwalle int networkDelta = compareNetwork(candidate, lastSelectedConfiguration); 1865b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (DBG && candidate != null) { 1866b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String doSwitch = ""; 1867b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle String current = ""; 1868b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (networkDelta < 0) { 1869b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle doSwitch = " -> not switching"; 1870b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1871b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle if (currentConfiguration != null) { 18722f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle current = " with current " + currentConfiguration.configKey(); 1873b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle } 1874b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle logDbg("attemptAutoJoin networkSwitching candidate " 1875b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + candidate.configKey() 1876b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + current 1877c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + " linked=" + (currentConfiguration != null 1878b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle && currentConfiguration.isLinked(candidate)) 1879b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + " : delta=" 1880b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + Integer.toString(networkDelta) + " " 1881b664cfeab6f02e24376ea0a15beb83d142f0b14dvandwalle + doSwitch); 1882b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 18834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1884931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle /** 1885931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * Ask WifiStateMachine permission to switch : 1886931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * if user is currently streaming voice traffic, 1887931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle * then we should not be allowed to switch regardless of the delta 1888931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle */ 188977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) { // !!! JNo: Here! 1890b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mStaStaSupported) { 1891b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("mStaStaSupported --> error do nothing now "); 1892b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1893b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) { 1894b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING; 1895b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1896b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING; 1897b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1898b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1899b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto connect with netId " 1900b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(candidate.networkId) 1901b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " to " + candidate.configKey()); 1902b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 19032451dbcc4f9641df188326215b204b798eb70c46vandwalle if (didOverride) { 19042451dbcc4f9641df188326215b204b798eb70c46vandwalle candidate.numScorerOverrideAndSwitchedNetwork++; 19052451dbcc4f9641df188326215b204b798eb70c46vandwalle } 1906c298087de50ea56c31a4ade7ee1e83b313bb63c7vandwalle candidate.numAssociation++; 1907e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoJoinAttempt++; 19089f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle 19092f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (candidate.BSSID == null || candidate.BSSID.equals("any")) { 19102f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // First step we selected the configuration we want to connect to 19112f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Second step: Look for the best Scan result for this configuration 19122f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // TODO this algorithm should really be done in one step 19132f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1914833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1915833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, candidate, mScanResultAutoJoinAge, null); 19162f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && currentBSSID != null 19172f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 19182f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // Sanity, we were already asociated to that candidate 19192f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle roamCandidate = null; 19202f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 19212f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && roamCandidate.is5GHz()) { 19222f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // If the configuration hasn't a default BSSID selected, and the best 19232f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // candidate is 5GHZ, then select this candidate so as WifiStateMachine and 19242f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle // supplicant will pick it first 19252f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle candidate.autoJoinBSSID = roamCandidate.BSSID; 19262f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (VDBG) { 19272f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle logDbg("AutoJoinController: lock to 5GHz " 19282f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + candidate.autoJoinBSSID 19292f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " RSSI=" + roamCandidate.level 19302f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle + " freq=" + roamCandidate.frequency); 19312f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle } 1932448c9536a302c58a79e271b1721c08b8882f800evandwalle } else { 1933448c9536a302c58a79e271b1721c08b8882f800evandwalle // We couldnt find a roam candidate 1934448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.autoJoinBSSID = "any"; 19359f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 19369f3349fa2cd39d690d1e2b7c3b71ced412e24f2cvandwalle } 1937448c9536a302c58a79e271b1721c08b8882f800evandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 1938448c9536a302c58a79e271b1721c08b8882f800evandwalle candidate.networkId, networkSwitchType, candidate); 193968fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 19404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1941b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 19424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1943b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (networkSwitchType == AUTO_JOIN_IDLE) { 1944e67ec726c07410073575473c0f50dc737629f5davandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 1945931338d1533d1bd11ba0e5aebb4e4b7b2c8ab056vandwalle // Attempt same WifiConfiguration roaming 1946833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle ScanResult roamCandidate = 1947833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle attemptRoam(null, currentConfiguration, mScanResultAutoJoinAge, currentBSSID); 1948e67ec726c07410073575473c0f50dc737629f5davandwalle /** 1949e67ec726c07410073575473c0f50dc737629f5davandwalle * TODO: (post L initial release) 1950e67ec726c07410073575473c0f50dc737629f5davandwalle * consider handling linked configurations roaming (i.e. extended Roaming) 1951e67ec726c07410073575473c0f50dc737629f5davandwalle * thru the attemptRoam function which makes use of the RSSI roaming threshold. 1952e67ec726c07410073575473c0f50dc737629f5davandwalle * At the moment, extended roaming is only handled thru the attemptAutoJoin() 1953e67ec726c07410073575473c0f50dc737629f5davandwalle * function which compare configurations. 1954e67ec726c07410073575473c0f50dc737629f5davandwalle * 1955e67ec726c07410073575473c0f50dc737629f5davandwalle * The advantage of making use of attemptRoam function is that this function 1956e67ec726c07410073575473c0f50dc737629f5davandwalle * will looks at all the BSSID of each configurations, instead of only looking 1957e67ec726c07410073575473c0f50dc737629f5davandwalle * at WifiConfiguration.visibility which keeps trackonly of the RSSI/band of the 1958e67ec726c07410073575473c0f50dc737629f5davandwalle * two highest BSSIDs. 1959e67ec726c07410073575473c0f50dc737629f5davandwalle */ 1960e67ec726c07410073575473c0f50dc737629f5davandwalle // Attempt linked WifiConfiguration roaming 1961e67ec726c07410073575473c0f50dc737629f5davandwalle /* if (currentConfiguration != null 1962e67ec726c07410073575473c0f50dc737629f5davandwalle && currentConfiguration.linkedConfigurations != null) { 1963e67ec726c07410073575473c0f50dc737629f5davandwalle for (String key : currentConfiguration.linkedConfigurations.keySet()) { 1964e67ec726c07410073575473c0f50dc737629f5davandwalle WifiConfiguration link = mWifiConfigStore.getWifiConfiguration(key); 1965e67ec726c07410073575473c0f50dc737629f5davandwalle if (link != null) { 1966833dcce8f6712f7594f06ea33208e3e106c15afcvandwalle roamCandidate = attemptRoam(roamCandidate, link, mScanResultAutoJoinAge, 1967e67ec726c07410073575473c0f50dc737629f5davandwalle currentBSSID); 1968e67ec726c07410073575473c0f50dc737629f5davandwalle } 1969e67ec726c07410073575473c0f50dc737629f5davandwalle } 1970e67ec726c07410073575473c0f50dc737629f5davandwalle }*/ 1971e67ec726c07410073575473c0f50dc737629f5davandwalle if (roamCandidate != null && currentBSSID != null 1972e67ec726c07410073575473c0f50dc737629f5davandwalle && currentBSSID.equals(roamCandidate.BSSID)) { 1973e67ec726c07410073575473c0f50dc737629f5davandwalle roamCandidate = null; 1974e67ec726c07410073575473c0f50dc737629f5davandwalle } 19752f2cf21662275a0e93d7d7a6ad3d98b4c596dcf0vandwalle if (roamCandidate != null && mWifiStateMachine.shouldSwitchNetwork(999)) { 1976b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1977b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto roam with netId " 1978b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(currentConfiguration.networkId) 1979b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " " + currentConfiguration.configKey() + " to BSSID=" 1980b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + roamCandidate.BSSID + " freq=" + roamCandidate.frequency 19811ec92c57244311c7fca3ab6b244a06c2b2b58902vandwalle + " RSSI=" + roamCandidate.level); 1982b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1983b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_ROAMING; 1984e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle mWifiConnectionStatistics.numAutoRoamAttempt++; 1985e8c89583e489d451880471b7cc7659bd9fa802f4vandwalle 1986b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM, 1987b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle currentConfiguration.networkId, 1, roamCandidate); 198868fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle found = true; 1989f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1990f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1991b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType)); 199268fee36dac1dda5c596c00ef33fdbc0962e9ec9fvandwalle return found; 1993f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 199477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 199577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private void logDenial(String reason, WifiConfiguration config) { 199677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (!DBG) { 199777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return; 199877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 199977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist logDbg(reason + config.toString()); 200077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 2001f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 2002f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 2003