WifiAutoJoinController.java revision 3a2a3d226881cce8a4e511302231d843b0def303
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; 20f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 21f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkKey; 22f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.NetworkScoreManager; 230c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport android.net.WifiKey; 24f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.wifi.WifiConfiguration; 25f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.wifi.ScanResult; 26f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.net.wifi.WifiManager; 27f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 28f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.SystemClock; 29b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalleimport android.os.Process; 30f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.util.Log; 31f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 320c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.ArrayList; 330c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalleimport java.util.Collection; 34f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Iterator; 35f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.HashMap; 36f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.List; 37f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport java.util.Date; 38f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 39f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle/** 40f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * AutoJoin controller is responsible for WiFi Connect decision 41f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 42f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * It runs in the thread context of WifiStateMachine 43f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 44f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 45f22d23092ab37286a5ef9d257d5bb32c421d2669vandwallepublic class WifiAutoJoinController { 46f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 47f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private Context mContext; 48f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiStateMachine mWifiStateMachine; 49f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiConfigStore mWifiConfigStore; 50f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiTrafficPoller mWifiTrafficPoller; 51f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNative mWifiNative; 52f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 53f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private NetworkScoreManager scoreManager; 54f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private WifiNetworkScoreCache mNetworkScoreCache; 55f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 56f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final String TAG = "WifiAutoJoinController "; 57ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean DBG = false; 58ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle private static boolean VDBG = false; 59f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final boolean mStaStaSupported = false; 60f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private static final int SCAN_RESULT_CACHE_SIZE = 80; 61f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 62453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle private String mCurrentConfigurationKey = null; //used by autojoin 63f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 64f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private HashMap<String, ScanResult> scanResultCache = 65f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle new HashMap<String, ScanResult>(); 66f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 6727355a942653264388e909a4276196ee63e57811vandwalle //lose the non-auth failure blacklisting after 8 hours 684dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListHardMilli = 1000 * 60 * 60 * 8; 6927355a942653264388e909a4276196ee63e57811vandwalle //lose some temporary blacklisting after 30 minutes 704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle private final static long loseBlackListSoftMilli = 1000 * 60 * 30; 7127355a942653264388e909a4276196ee63e57811vandwalle 72b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_IDLE = 0; 73b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_ROAMING = 1; 74b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_EXTENDED_ROAMING = 2; 75b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3; 76b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 77f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s, 78f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiTrafficPoller t, WifiNative n) { 79f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mContext = c; 80f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine = w; 81f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore = s; 82f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiTrafficPoller = t; 83f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiNative = n; 84f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 8521bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle scoreManager = 8621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle (NetworkScoreManager) mContext.getSystemService(Context.NETWORK_SCORE_SERVICE); 87f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager == null) 88f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("Registered scoreManager NULL " + " service " + Context.NETWORK_SCORE_SERVICE); 89f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 90f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (scoreManager != null) { 91f13817203179f41620514718c8668ae7e418f8afJeff Davidson mNetworkScoreCache = new WifiNetworkScoreCache(mContext); 92f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache); 93f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 94f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("No network score service: Couldnt register as a WiFi score Manager, type=" 95f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(NetworkKey.TYPE_WIFI) 96f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " service " + Context.NETWORK_SCORE_SERVICE); 97f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mNetworkScoreCache = null; 98f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 99f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 100f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 101ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle void enableVerboseLogging(int verbose) { 102ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (verbose > 0 ) { 103abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = true; 104ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = true; 105ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } else { 106abde872adced15dfb6781fb71959453d963326dbYuhao Zheng DBG = false; 107ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle VDBG = false; 108ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 109ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 110ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle 11121bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle int mScanResultMaximumAge = 30000; /* milliseconds unit */ 112f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 113ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /* 114ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * flush out scan results older than mScanResultMaximumAge 115ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * 116ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * */ 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private void ageScanResultsOut(int delay) { 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (delay <= 0) { 119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle delay = mScanResultMaximumAge; //something sane 120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 121b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long milli = System.currentTimeMillis(); 122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("ageScanResultsOut delay " + Integer.valueOf(delay) + " size " 124f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.valueOf(scanResultCache.size()) + " now " + Long.valueOf(milli)); 125f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 126f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 127f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Iterator<HashMap.Entry<String,ScanResult>> iter = scanResultCache.entrySet().iterator(); 128f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (iter.hasNext()) { 129f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle HashMap.Entry<String,ScanResult> entry = iter.next(); 130f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult result = entry.getValue(); 131f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 132f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.seen + delay) < milli) { 133f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle iter.remove(); 134f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 135f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 136f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 137f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 138f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void addToScanCache(List<ScanResult> scanList) { 139f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration associatedConfig; 140f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1410c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle ArrayList<NetworkKey> unknownScanResults = new ArrayList<NetworkKey>(); 1420c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 143f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for(ScanResult result: scanList) { 1441fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (result.SSID == null) continue; 145f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.seen = System.currentTimeMillis(); 146f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 147f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ScanResult sr = scanResultCache.get(result.BSSID); 148f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (sr != null) { 149f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // if there was a previous cache result for this BSSID, average the RSSI values 150f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 151f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int previous_rssi = sr.level; 152f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle long previously_seen_milli = sr.seen; 153f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 154f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* average RSSI with previously seen instances of this scan result */ 155f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int avg_rssi = result.level; 156f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 157f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((previously_seen_milli > 0) 158f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && (previously_seen_milli < mScanResultMaximumAge/2)) { 159f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* 160f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 161f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * previously_seen_milli = 0 => RSSI = 0.5 * previous_seen_rssi + 0.5 * new_rssi 162f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 163f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If previously_seen_milli is 15+ seconds old: 164f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * previously_seen_milli = 15000 => RSSI = new_rssi 165f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * 166f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 167f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 168f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle double alpha = 0.5 - (double)previously_seen_milli 169f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle / (double)mScanResultMaximumAge; 170f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 171f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle avg_rssi = (int)((double)avg_rssi * (1-alpha) + (double)previous_rssi * alpha); 172f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 173f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.level = avg_rssi; 174f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //remove the previous Scan Result 176f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.remove(result.BSSID); 1770c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } else { 1780c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (!mNetworkScoreCache.isScoredNetwork(result)) { 17921bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle WifiKey wkey; 18021bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle //TODO : find out how we can get there without a valid UTF-8 encoded SSID 18121bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle //TODO: which will cause WifiKey constructor to fail 18221bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle try { 18321bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle wkey = new WifiKey("\"" + result.SSID + "\"", result.BSSID); 18421bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle } catch (IllegalArgumentException e) { 18521bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("AutoJoinController: received badly encoded SSID=[" + result.SSID + 18621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle "] ->skipping this network"); 18721bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle wkey = null; 18821bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle } 18921bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle if (wkey != null) { 19021bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle NetworkKey nkey = new NetworkKey(wkey); 19121bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle //if we don't know this scan result then request a score to Herrevad 19221bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle unknownScanResults.add(nkey); 19321bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle } 1940c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 195f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 196f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 197f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle scanResultCache.put(result.BSSID, new ScanResult(result)); 198f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 199f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //add this BSSID to the scanResultCache of the relevant WifiConfiguration 200f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.updateSavedNetworkHistory(result); 201f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 2020c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //try to associate this BSSID to an existing Saved WifiConfiguration 203f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (associatedConfig == null) { 204f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle associatedConfig = mWifiConfigStore.associateWithConfiguration(result); 2051fcf3c6d2b9ed65573e1e7c55fc5a30ebd364c4fYuhao Zheng if (associatedConfig != null && associatedConfig.SSID != null) { 206f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 207f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("addToScanCache save associated config " 208f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + associatedConfig.SSID + " with " + associatedConfig.SSID); 209f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 210f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiStateMachine.sendMessage(WifiManager.SAVE_NETWORK, associatedConfig); 211f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 212f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 213f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 2140c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle 2150c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle if (unknownScanResults.size() != 0) { 2160c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle NetworkKey[] newKeys = 2170c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle unknownScanResults.toArray(new NetworkKey[unknownScanResults.size()]); 2180c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle //kick the score manager, we will get updated scores asynchronously 2190c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle scoreManager.requestScores(newKeys); 2200c8b99a3b78e458a5617cc449e2efe69c5bdd531vandwalle } 221f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 222f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 223f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void logDbg(String message) { 2240888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle logDbg(message, false); 225ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 226ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 227ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle void logDbg(String message, boolean stackTrace) { 228f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle long now = SystemClock.elapsedRealtimeNanos(); 2290888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle String ts = String.format("[%,d us] ", now / 1000); 230ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (stackTrace) { 231ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle Log.e(TAG, ts + message + " stack:" 232ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[2].getMethodName() + " - " 233ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[3].getMethodName() + " - " 234ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[4].getMethodName() + " - " 235ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Thread.currentThread().getStackTrace()[5].getMethodName()); 236ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else { 237ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle Log.e(TAG, ts + message); 238ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 239f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 240f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 241f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* called directly from WifiStateMachine */ 242f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newSupplicantResults() { 243f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<ScanResult> scanList = mWifiStateMachine.syncGetScanResultsList(); 244f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 245f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(mScanResultMaximumAge); 246f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (DBG) 247f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("newSupplicantResults size=" + Integer.valueOf(scanResultCache.size()) ); 248f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 249f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 250f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore.writeKnownNetworkHistory(); 251f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 252f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 253f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 254f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 255f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* not used at the moment 256f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * should be a call back from WifiScanner HAL ?? 257f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * this function is not hooked and working yet, it will receive scan results from WifiScanners 258f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * with the list of IEs,then populate the capabilities by parsing the IEs and inject the scan 259f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * results as normal. 260f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle */ 261f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void newHalScanResults() { 262f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle List<ScanResult> scanList = null;//mWifiScanner.syncGetScanResultsList(); 263f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String akm = WifiParser.parse_akm(null, null); 264f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(akm); 265f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle addToScanCache(scanList); 266f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ageScanResultsOut(0); 267f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 268f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle mWifiConfigStore.writeKnownNetworkHistory(); 269f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 270f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 271f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* network link quality changed, called directly from WifiTrafficPoller, 272f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle or by listening to Link Quality intent */ 273f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void linkQualitySignificantChange() { 274f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle attemptAutoJoin(); 275f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 276f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 277f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* 278f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * compare a WifiConfiguration against the current network, return a delta score 279f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * If not associated, and the candidate will always be better 280f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * For instance if the candidate is a home network versus an unknown public wifi, 281f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle * the delta will be infinite, else compare Kepler scores etc… 282b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * Negatve return values from this functions are meaningless per se, just trying to 283b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle * keep them distinct for debug purpose (i.e. -1, -2 etc...) 284f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle ***/ 285f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle private int compareNetwork(WifiConfiguration candidate) { 286b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (candidate == null) 287b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -3; 288b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 289f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration currentNetwork = mWifiStateMachine.getCurrentWifiConfiguration(); 290b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentNetwork == null) { 291b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return 1000; 292b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 293f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 294f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate.configKey(true).equals(currentNetwork.configKey(true))) { 295b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle return -2; 296f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 297f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 298f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = compareWifiConfigurations(currentNetwork, candidate); 299f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 300f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 301f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //ascending: currentNetwork < candidate 302f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 10; //will try switch over to the candidate 303f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 304f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 305f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 306f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 307f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 308ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle /** 309ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * update the network history fields fo that configuration 310ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if userTriggered, we mark the configuration as "non selfAdded" since the user has seen it 311ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * and took over management 312ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * - if it is a "connect", remember which network were there at the point of the connect, so 313ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * as those networks get a relative lower score than the selected configuration 31462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle * 315ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param netId 316ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param userTriggered : if the update come from WiFiManager 317ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle * @param connect : if the update includes a connect 318117be607246604e875de62aa8cdd99700b77a2b4vandwalle **/ 31962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle public void updateConfigurationHistory(int netId, boolean userTriggered, boolean connect) { 320f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration selected = mWifiConfigStore.getWifiConfiguration(netId); 321f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected == null) { 322f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 323f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 324f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 325e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (selected.SSID == null) { 326e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle return; 327e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 328e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 32962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (userTriggered) { 330ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // reenable autojoin for this network, 33162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle // since the user want to connect to this configuration 33227355a942653264388e909a4276196ee63e57811vandwalle selected.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 33362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.selfAdded = false; 33462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 335f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 336992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG && userTriggered) { 337f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (selected.connectChoices != null) { 338ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 339f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(netId) + " now: " 340992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(selected.connectChoices.size()) 341992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 342f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 343ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will update " 344992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(netId) 345992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " uid=" + Integer.toString(selected.creatorUid), true); 346f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 347f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 348f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 349ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (connect && userTriggered) { 350ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle boolean found = false; 35162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle List<WifiConfiguration> networks = 35262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle mWifiConfigStore.getRecentConfiguredNetworks(12000, false); 35362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (networks != null) { 35462f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle for (WifiConfiguration config : networks) { 355992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (DBG) { 356992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle logDbg("updateConfigurationHistory got " + config.SSID + " nid=" 357992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + Integer.toString(config.networkId)); 358992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 359f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 36062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.configKey(true).equals(config.configKey(true))) { 361ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle found = true; 36262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 36362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 364f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 36562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle int rssi = WifiConfiguration.INVALID_RSSI; 36662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.visibility != null) { 36762f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle rssi = config.visibility.rssi5; 36862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.visibility.rssi24 > rssi) 36962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle rssi = config.visibility.rssi24; 37062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 37162f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (rssi < -80) { 37262f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle continue; 37362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 374f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 375ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //the selected configuration was preferred over a recently seen config 376ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //hence remember the user's choice: 377ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle //add the recently seen config to the selected's connectChoices array 378ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 379ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (selected.connectChoices == null) { 380ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle selected.connectChoices = new HashMap<String, Integer>(); 381ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 382ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 383ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory add a choice " + selected.configKey(true) 3840888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle + " over " + config.configKey(true) 385992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle + " RSSI " + Integer.toString(rssi)); 386cf5b8eb8a08c45bd4a82f1f4bb789c8a1b08744fvandwalle 3870888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle //add the visible config to the selected's connect choice list 38862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle selected.connectChoices.put(config.configKey(true), rssi); 389f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 39062f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (config.connectChoices != null) { 391ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 392ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory will remove " 39362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + selected.configKey(true) + " from " + config.configKey(true)); 394ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 3950888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle //remove the selected from the recently seen config's connectChoice list 39662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle config.connectChoices.remove(selected.configKey(true)); 3970888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 3980888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (selected.linkedConfigurations != null) { 3990888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle //remove the selected's linked configuration from the 4000888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle //recently seen config's connectChoice list 4010888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle for (String key : selected.linkedConfigurations.keySet()) { 4020888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle config.connectChoices.remove(key); 4030888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 4040888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 40562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 406ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 407ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (found == false) { 408ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // log an error for now but do something stringer later 409ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // we will need a new scan before attempting to connect to this 410ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle // configuration anyhow and thus we can process the scan results then 411ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory try to connect to an old network!! : " 412ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + selected.configKey()); 41362f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 414f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 41562f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (selected.connectChoices != null) { 41662f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle if (VDBG) 417ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle logDbg("updateConfigurationHistory " + Integer.toString(netId) 41862f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle + " now: " + Integer.toString(selected.connectChoices.size())); 41962f1d0ca8ea4466628f6ff179b1f20e1279fa7e0vandwalle } 420f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 421f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 422992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle 423992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle //TODO: write only if something changed 424992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle if (userTriggered || connect) { 425992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle mWifiConfigStore.writeKnownNetworkHistory(); 426992ae00f25a9cc22cf5db3261bd7e72927069cf7vandwalle } 427f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 428f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 429f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void printChoices(WifiConfiguration config) { 430f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int num = 0; 431f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices!= null) { 432f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle num = config.connectChoices.size(); 433f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 434f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 435f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("printChoices " + config.SSID + " num choices: " + Integer.toString(num)); 436f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices!= null) { 437f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : config.connectChoices.keySet()) { 438f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg(" " + key); 439f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 440f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 441f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 442f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 443f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean hasConnectChoice(WifiConfiguration source, WifiConfiguration target) { 444f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean found = false; 445f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (source == null) 446f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return false; 447f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (target == null) 448f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return false; 449f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 450f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (source.connectChoices != null) { 451f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ( source.connectChoices.get(target.configKey(true)) != null) { 452f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 453f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 454f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 455f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 456f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (source.linkedConfigurations != null) { 457f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : source.linkedConfigurations.keySet()) { 458f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(key); 459f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config != null) { 460f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices != null) { 461f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.connectChoices.get(target.configKey(true)) != null) { 462f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle found = true; 463f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 464f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 465f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 466f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 4674dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 468f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 469f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return found; 470f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 471f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 472f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurationsRSSI(WifiConfiguration a, WifiConfiguration b) { 473f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 474f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int boost5 = 25; 475f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 476f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 477f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 478453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //error -> cant happen, need to throw en exception 479f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("compareWifiConfigurations NULL band status!"); 480f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 481f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 482453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((astatus.rssi5 > -70) && (bstatus.rssi5 == WifiConfiguration.INVALID_RSSI) 4834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle && ((astatus.rssi5 + boost5) > (bstatus.rssi24))) { 484f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is seen on 5GHz with good RSSI, greater rssi than b 485f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 486f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 487453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else if ((bstatus.rssi5 > -70) && (astatus.rssi5 == WifiConfiguration.INVALID_RSSI) 4884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle && ((bstatus.rssi5 + boost5) > (bstatus.rssi24))) { 489f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //b is seen on 5GHz with good RSSI, greater rssi than a 490f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 491f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = 1; 492f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 493f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 494f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 495f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 4964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 497f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int compareWifiConfigurations(WifiConfiguration a, WifiConfiguration b) { 498f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = 0; 499117be607246604e875de62aa8cdd99700b77a2b4vandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 500f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle boolean linked = false; 501f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 502453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if ((a.linkedConfigurations != null) && (b.linkedConfigurations != null) 503453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (a.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED) 504453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle && (b.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED)) { 505f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((a.linkedConfigurations.get(b.configKey(true))!= null) 506f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && (b.linkedConfigurations.get(a.configKey(true))!= null)) { 507f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle linked = true; 508f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 509f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 510f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 511f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.ephemeral && b.ephemeral == false) { 512f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 513453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations ephemeral and prefers " + b.configKey() 514453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + a.configKey()); 515f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 516f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 1; //b is of higher priority - ascending 517f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 518f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (b.ephemeral && a.ephemeral == false) { 519f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 520453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations ephemeral and prefers " +a.configKey() 521453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey()); 522f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 523f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return -1; //a is of higher priority - descending 524f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 525f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5264dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int aRssiBoost5 = 0; 5274dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int bRssiBoost5 = 0; 528453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //apply Hysteresis: boost the RSSI value of the currently connected configuration 529453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle int aRssiBoost = 0; 530453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle int bRssiBoost = 0; 531453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (null != mCurrentConfigurationKey) { 532453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (a.configKey().equals(mCurrentConfigurationKey)) { 533453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle aRssiBoost += 10; 534453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else if (b.configKey().equals(mCurrentConfigurationKey)) { 535453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle bRssiBoost += 10; 536453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 537453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 538f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (linked) { 5394dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int ascore; 5404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int bscore; 541f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // then we try prefer 5GHz, and try to ignore user's choice 542f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility astatus = a.visibility; 543f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility bstatus = b.visibility; 544f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (astatus == null || bstatus == null) { 545f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //error 546f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("compareWifiConfigurations NULL band status!"); 547f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return 0; 548f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 549f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 550f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 551f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("compareWifiConfigurations linked: " + Integer.toString(astatus.rssi5) 552f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + "," + Integer.toString(astatus.rssi24) + " " 553f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(bstatus.rssi5) + "," 554f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(bstatus.rssi24)); 555f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 556f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //Boost RSSI value of 5GHz bands iff the base value is better than -65 5584dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas 5594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //we prefer 2.4GHz otherwise. 5604dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //Note that 2.4GHz doesn't need a boost since at equal power the RSSI is 6-10 dB higher 5614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((astatus.rssi5+aRssiBoost) > WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD) { 5624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle aRssiBoost5 = 25; 5634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 5644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((bstatus.rssi5+bRssiBoost) > WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD) { 5654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle bRssiBoost5 = 25; 5664dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 567f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 5684dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (astatus.rssi5+aRssiBoost5 > astatus.rssi24) { 5694dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //prefer a's 5GHz 5704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle ascore = astatus.rssi5 + aRssiBoost5 + aRssiBoost; 5714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else { 5724dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //prefer a's 2.4GHz 5734dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle ascore = astatus.rssi24 + aRssiBoost; 5744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 5754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (bstatus.rssi5+bRssiBoost5 > bstatus.rssi24) { 5764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //prefer b's 5GHz 5774dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle bscore = bstatus.rssi5 + bRssiBoost5 + bRssiBoost; 5784dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else { 5794dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //prefer b's 2.4GHz 5804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle bscore = bstatus.rssi24 + bRssiBoost; 5814dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 5824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (ascore > bscore) { 5834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //a is seen on 5GHz with good RSSI, greater rssi than b 5844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //a is of higher priority - descending 5854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle order = -10; 586f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 587453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations linked and prefers " + a.configKey() 5884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + a.visibility.rssi24 5894dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + a.visibility.rssi5 5904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + a.visibility.num24 5914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + a.visibility.num5 + ")" 592453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 5934dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + b.visibility.rssi24 5944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + b.visibility.rssi5 5954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + b.visibility.num24 5964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + b.visibility.num5 + ")" 5974dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " due to RSSI"); 598f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 5994dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if (bscore > ascore) { 6004dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //b is seen on 5GHz with good RSSI, greater rssi than a 6014dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //a is of lower priority - ascending 6024dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle order = 10; 6034dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 604453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations linked and prefers " + b.configKey() 6054dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + b.visibility.rssi24 6064dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + b.visibility.rssi5 6074dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + b.visibility.num24 6084dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + b.visibility.num5 + ")" 6094dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " over " + a.configKey() 6104dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + a.visibility.rssi24 6114dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + a.visibility.rssi5 6124dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + a.visibility.num24 6134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + a.visibility.num5 + ")" 6144dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " due to RSSI"); 615f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 616f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 617f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 618ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 619ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //compare by user's choice. 620f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (hasConnectChoice(a, b)) { 621f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 622f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = order -2; 623f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 624453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers -2 " + a.configKey() 625453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() 626ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + " due to user choice order -> " + Integer.toString(order)); 627f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 628f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 629f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 630f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (hasConnectChoice(b, a)) { 631f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 632f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = order + 2; 633f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 634453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +2 " + b.configKey() + " over " 635453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to user choice order ->" + Integer.toString(order)); 636f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 637f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 638f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 639ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //TODO count the number of association rejection 640ede1310be531a84faa08f02c3fd243448dd936ddvandwalle // and use this to adjust the order by more than +/- 3 641ede1310be531a84faa08f02c3fd243448dd936ddvandwalle if ((a.status == WifiConfiguration.Status.DISABLED) 642ede1310be531a84faa08f02c3fd243448dd936ddvandwalle && (a.disableReason == WifiConfiguration.DISABLED_ASSOCIATION_REJECT)) { 643ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //a is of lower priority - ascending 644ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //lower the comparison score a bit 645ede1310be531a84faa08f02c3fd243448dd936ddvandwalle order = order +3; 646ede1310be531a84faa08f02c3fd243448dd936ddvandwalle } 647ede1310be531a84faa08f02c3fd243448dd936ddvandwalle if ((b.status == WifiConfiguration.Status.DISABLED) 648ede1310be531a84faa08f02c3fd243448dd936ddvandwalle && (b.disableReason == WifiConfiguration.DISABLED_ASSOCIATION_REJECT)) { 649ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //a is of higher priority - descending 650ede1310be531a84faa08f02c3fd243448dd936ddvandwalle //lower the comparison score a bit 651ede1310be531a84faa08f02c3fd243448dd936ddvandwalle order = order -3; 652ede1310be531a84faa08f02c3fd243448dd936ddvandwalle } 653ede1310be531a84faa08f02c3fd243448dd936ddvandwalle 654ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if ((lastSelectedConfiguration != null) 655ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle && a.configKey().equals(lastSelectedConfiguration)) { 6564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // a is the last selected configuration, so keep it above connect choices (+/-2) and 6574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // above RSSI based selection of linked configuration (+/- 11) 6584dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // by giving a -11 659c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // Additional other factors like BAD RSSI (still to do) and 660c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // ASSOC_REJECTION high counts will then still 6614dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // tip the auto-join to roam 6624dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle order = order - 11; 663ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 6644dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("compareWifiConfigurations prefers -11 " + a.configKey() 665453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() + " because a is the last selected -> " 666ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Integer.toString(order)); 667ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 668ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } else if ((lastSelectedConfiguration != null) 669ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle && b.configKey().equals(lastSelectedConfiguration)) { 6704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // b is the last selected configuration, so keep it above connect choices (+/-2) and 6714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // above RSSI based selection of linked configuration (+/- 11) 6724dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // by giving a +11 673c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // Additional other factors like BAD RSSI (still to do) and 674c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // ASSOC_REJECTION high counts will then still 6754dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle // tip the auto-join to roam 6764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle order = order + 11; 677ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle if (VDBG) { 6784dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("compareWifiConfigurations prefers +11 " + a.configKey() 679453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + " over " + b.configKey() + " because b is the last selected -> " 680ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle + Integer.toString(order)); 681ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 682ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle } 683ecd2b88214b5d214fd1f63a9560caff9058912ddvandwalle 684f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order == 0) { 685f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we don't know anything - pick the last seen i.e. K behavior 686f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //we should do this only for recently picked configurations 687f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (a.priority > b.priority) { 688f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of higher priority - descending 689f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 690453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers -1 " + a.configKey() + " over " 691453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " due to priority"); 692f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 693f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 694f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = -1; 695f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else if (a.priority < b.priority) { 696f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //a is of lower priority - ascending 697f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 698453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +1 " + b.configKey() + " over " 699453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to priority"); 700f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 701f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 702f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = 1; 703f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 704f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //maybe just look at RSSI or band 705f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 706453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations prefers +1 " + b.configKey() + " over " 707453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + a.configKey() + " due to nothing"); 708f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 709f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 710f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle order = compareWifiConfigurationsRSSI(a, b); //compare RSSI 711f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 712f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 713f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 714f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String sorder = " == "; 715f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) 716f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " < "; 717f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order < 0) 718f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle sorder = " > "; 719f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 720f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 721453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("compareWifiConfigurations Done: " + a.configKey() + sorder 722453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + b.configKey() + " order " + Integer.toString(order)); 723f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 724f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 725f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return order; 726f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 727f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 728b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle /* attemptRoam function implement the core of the same SSID switching algorithm */ 729b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle ScanResult attemptRoam(WifiConfiguration current, int age) { 7304dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle ScanResult a = null; 731b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current == null) { 732b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 733b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam not associated"); 734b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 7354dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle return null; 7364dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 737b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current.scanResultCache == null) { 738b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 739b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam no scan cache"); 740b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 7414dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle return null; 7424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 743b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle if (current.scanResultCache.size() > 6) { 744b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) { 745c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam scan cache size " 746c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + current.scanResultCache.size() + " --> bail"); 747b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 748c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle //implement same SSID roaming only for configurations 749c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // that have less than 4 BSSIDs 7504dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle return null; 7514dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 752b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle String currentBSSID = mWifiStateMachine.getCurrentBSSID(); 753b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentBSSID == null) { 754b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 755b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptRoam currentBSSID unknown"); 756b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 757b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle return null; 758b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 759b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 760b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (current.bssidOwnerUid!= 0 && current.bssidOwnerUid != Process.WIFI_UID) { 761b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 762c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptRoam BSSID owner is " 763c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Long.toString(current.bssidOwnerUid) + " -> bail"); 764b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 7654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle return null; 7664dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 7674dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 768c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle //determine which BSSID we want to associate to, taking account 769c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle // relative strength of 5 and 2.4 GHz BSSIDs 7704dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle long now_ms = System.currentTimeMillis(); 7714dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int bRssiBoost5 = 0; 7724dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int aRssiBoost5 = 0; 7734dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int bRssiBoost = 0; 7744dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle int aRssiBoost = 0; 775b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle for (ScanResult b : current.scanResultCache.values()) { 7764dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 7773a2a3d226881cce8a4e511302231d843b0def303vandwalle if ((b.seen == 0) || (b.BSSID == null)) { 7784dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 7793a2a3d226881cce8a4e511302231d843b0def303vandwalle } 7804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 7813a2a3d226881cce8a4e511302231d843b0def303vandwalle if (b.status != ScanResult.ENABLED) { 7824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 7833a2a3d226881cce8a4e511302231d843b0def303vandwalle } 7844dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 7854dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now_ms - b.seen) > age) continue; 7864dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 7874dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //pick first one 7884dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (a == null) { 7894dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle a = b; 7904dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle continue; 7914dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 7924dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 793b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentBSSID.equals(b.BSSID)) { 794c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle //reduce the benefit of hysteresis if RSSI <= -75 795c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level <= WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) { 796c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle bRssiBoost = +6; 797c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 798c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle bRssiBoost = +10; 799c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 8004dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 801b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentBSSID.equals(a.BSSID)) { 802c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (a.level <= WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) { 803c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle //reduce the benefit of hysteresis if RSSI <= -75 804c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle aRssiBoost = +6; 805c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else { 806c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle aRssiBoost = +10; 807c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 8084dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 809c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.is5GHz() && (b.level+bRssiBoost) 810c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle > WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD) { 8114dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle bRssiBoost5 = 25; 812c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else if (b.is5GHz() && (b.level+bRssiBoost) 813c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle < WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) { 814c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle bRssiBoost5 = -10; 8154dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 816c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (a.is5GHz() && (a.level+aRssiBoost) 817c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle > WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD) { 8184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle aRssiBoost5 = 25; 819c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } else if (a.is5GHz() && (a.level+aRssiBoost) 820c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle < WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) { 821c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle aRssiBoost5 = -10; 8224dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 8234dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 8244dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (VDBG) { 825c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle String comp = " < "; 826c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 827c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle comp = " > "; 828c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 8294dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptRoam: " 830c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost) 831c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency + comp 832c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost) 833c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency); 834c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle } 835c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle 836c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle if (b.level + bRssiBoost + bRssiBoost5 > a.level +aRssiBoost + aRssiBoost5) { 837c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle //b is the better BSSID 838c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle a = b; 8394dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 8404dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 8413a2a3d226881cce8a4e511302231d843b0def303vandwalle if (a != null) { 8423a2a3d226881cce8a4e511302231d843b0def303vandwalle if (VDBG) { 8433a2a3d226881cce8a4e511302231d843b0def303vandwalle logDbg("attemptRoam: Found " 8443a2a3d226881cce8a4e511302231d843b0def303vandwalle + a.BSSID + " rssi=" + a.level + " freq=" + a.frequency 8453a2a3d226881cce8a4e511302231d843b0def303vandwalle + " Current: " + currentBSSID); 8463a2a3d226881cce8a4e511302231d843b0def303vandwalle } 8473a2a3d226881cce8a4e511302231d843b0def303vandwalle if (currentBSSID.equals(a.BSSID)) { 8483a2a3d226881cce8a4e511302231d843b0def303vandwalle return null; 8493a2a3d226881cce8a4e511302231d843b0def303vandwalle } 8504dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 8513a2a3d226881cce8a4e511302231d843b0def303vandwalle return a; 8524dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 8534dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 8544dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle /* attemptAutoJoin function implement the core of the a network switching algorithm */ 855f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle void attemptAutoJoin() { 856b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkSwitchType = AUTO_JOIN_IDLE; 8574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 8588c9088d11880553458f09377cc60d6eb7e66747bvandwalle String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); 8598c9088d11880553458f09377cc60d6eb7e66747bvandwalle 86027355a942653264388e909a4276196ee63e57811vandwalle // reset the currentConfiguration Key, and set it only if WifiStateMachine and 861453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle // supplicant agree 862453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = null; 863453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle WifiConfiguration currentConfiguration = mWifiStateMachine.getCurrentWifiConfiguration(); 864453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 865f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration candidate = null; 866f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 867f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* obtain the subset of recently seen networks */ 86827355a942653264388e909a4276196ee63e57811vandwalle List<WifiConfiguration> list = mWifiConfigStore.getRecentConfiguredNetworks(3000, false); 869f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (list == null) { 870f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) logDbg("attemptAutoJoin nothing"); 871f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return; 872f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 873f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 874f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* find the currently connected network: ask the supplicant directly */ 875f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String val = mWifiNative.status(); 876f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle String status[] = val.split("\\r?\\n"); 877f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 878f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle logDbg("attemptAutoJoin() status=" + val + " split=" 879f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + Integer.toString(status.length)); 880f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 881f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 882b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int supplicantNetId = -1; 883f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (String key : status) { 884f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (key.regionMatches(0, "id=", 0, 3)) { 885f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int idx = 3; 886b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId = 0; 887f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle while (idx < key.length()) { 888f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle char c = key.charAt(idx); 889f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 890f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((c >= 0x30) && (c <= 0x39)) { 891b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId *= 10; 892b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle supplicantNetId += c - 0x30; 893f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle idx++; 894f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 895f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle break; 896f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 897f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 898f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 899f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 900ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 901ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin() num recent config " + Integer.toString(list.size()) 902b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + " ---> suppId=" + Integer.toString(supplicantNetId)); 903ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 904f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 905453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle if (currentConfiguration != null) { 906b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (supplicantNetId != currentConfiguration.networkId) { 907453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin() ERROR wpa_supplicant out of sync nid=" 908b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + Integer.toString(supplicantNetId) + " WifiStateMachine=" 909453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle + Integer.toString(currentConfiguration.networkId)); 910b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle mWifiStateMachine.disconnectCommand(); 911b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle return; 912453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } else { 913453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle mCurrentConfigurationKey = currentConfiguration.configKey(); 914453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 915453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle } 916453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 917b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle int currentNetId = -1; 918b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (currentConfiguration != null) { 919b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // if we are associated to a configuration, it will 920b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle // be compared thru the compareNetwork function 921b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle currentNetId = currentConfiguration.networkId; 922b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle } 923b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle 924c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle /* run thru all visible configurations without looking at the one we 925c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle * are currently associated to 9264dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * select Best Network candidate from known WifiConfigurations 9274dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle * */ 928f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (WifiConfiguration config : list) { 929f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((config.status == WifiConfiguration.Status.DISABLED) 930f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle && (config.disableReason == WifiConfiguration.DISABLED_AUTH_FAILURE)) { 931ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 932b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("attemptAutoJoin skip candidate due to auth failure: " 933ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + config.configKey(true)); 934ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 935f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 936f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 937453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle 938e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle if (config.SSID == null) { 939b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle continue; 940e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle } 941e86c962bb99a8b126ed64ddcc6b112161549e26dvandwalle 94227355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 94327355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) { 944453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle //avoid temporarily disabled networks altogether 9454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle //TODO: implement a better logic which will re-enable the network after some time 946ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 947ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle logDbg("attemptAutoJoin skip candidate due to auto join status " 948ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + Integer.toString(config.autoJoinStatus) + " key " 949ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + config.configKey(true)); 950ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 951f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 952f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 953f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 95427355a942653264388e909a4276196ee63e57811vandwalle //try to unblacklist based on elapsed time 95527355a942653264388e909a4276196ee63e57811vandwalle if (config.blackListTimestamp > 0) { 95627355a942653264388e909a4276196ee63e57811vandwalle long now = System.currentTimeMillis(); 95727355a942653264388e909a4276196ee63e57811vandwalle if (now < config.blackListTimestamp) { 958c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle //looks like there was a change in the system clock since we black listed, and 95927355a942653264388e909a4276196ee63e57811vandwalle //timestamp is not meaningful anymore, hence lose it. 96027355a942653264388e909a4276196ee63e57811vandwalle //this event should be rare enough so that we still want to lose the black list 96127355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 96227355a942653264388e909a4276196ee63e57811vandwalle } else { 9634dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if ((now - config.blackListTimestamp) > loseBlackListHardMilli) { 96427355a942653264388e909a4276196ee63e57811vandwalle //reenable it after 18 hours, i.e. next day 96527355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_ENABLED); 9664dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } else if ((now - config.blackListTimestamp) > loseBlackListSoftMilli) { 96727355a942653264388e909a4276196ee63e57811vandwalle //lose blacklisting due to bad link 96827355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 8); 96927355a942653264388e909a4276196ee63e57811vandwalle } 97027355a942653264388e909a4276196ee63e57811vandwalle } 97127355a942653264388e909a4276196ee63e57811vandwalle } 97227355a942653264388e909a4276196ee63e57811vandwalle 97327355a942653264388e909a4276196ee63e57811vandwalle //try to unblacklist based on good visibility 97427355a942653264388e909a4276196ee63e57811vandwalle if (config.visibility.rssi5 < WifiConfiguration.UNBLACKLIST_THRESHOLD_5_SOFT 97527355a942653264388e909a4276196ee63e57811vandwalle && config.visibility.rssi24 < WifiConfiguration.UNBLACKLIST_THRESHOLD_24_SOFT) { 97627355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 97727355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin skip candidate due to auto join status " 9784dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 9794dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) 9804dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " rssi=(" + config.visibility.rssi24 9814dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.rssi5 9824dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 9834dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 98427355a942653264388e909a4276196ee63e57811vandwalle } 98527355a942653264388e909a4276196ee63e57811vandwalle } else if (config.visibility.rssi5 < WifiConfiguration.UNBLACKLIST_THRESHOLD_5_HARD 98627355a942653264388e909a4276196ee63e57811vandwalle && config.visibility.rssi24 < WifiConfiguration.UNBLACKLIST_THRESHOLD_24_HARD) { 98727355a942653264388e909a4276196ee63e57811vandwalle // if the network is simply temporary disabled, don't allow reconnect until 98827355a942653264388e909a4276196ee63e57811vandwalle // rssi becomes good enough 98927355a942653264388e909a4276196ee63e57811vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 1); 99027355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 99127355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin good candidate seen, bumped soft -> status=" 99227355a942653264388e909a4276196ee63e57811vandwalle + config.autoJoinStatus 9934dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) + " rssi=(" 9944dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 9954dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 9964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 99727355a942653264388e909a4276196ee63e57811vandwalle } 99827355a942653264388e909a4276196ee63e57811vandwalle } else { 999c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle config.setAutoJoinStatus(config.autoJoinStatus - 3); 100027355a942653264388e909a4276196ee63e57811vandwalle if (DBG) { 100127355a942653264388e909a4276196ee63e57811vandwalle logDbg("attemptAutoJoin good candidate seen, bumped hard -> status=" 100227355a942653264388e909a4276196ee63e57811vandwalle + config.autoJoinStatus 10034dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) + " rssi=(" 10044dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 10054dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 10064dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 100727355a942653264388e909a4276196ee63e57811vandwalle } 100827355a942653264388e909a4276196ee63e57811vandwalle } 100927355a942653264388e909a4276196ee63e57811vandwalle 101027355a942653264388e909a4276196ee63e57811vandwalle if (config.autoJoinStatus >= 101127355a942653264388e909a4276196ee63e57811vandwalle WifiConfiguration.AUTO_JOIN_TEMPORARY_DISABLED) { 101227355a942653264388e909a4276196ee63e57811vandwalle //network is blacklisted, skip 10134dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (DBG) { 10144dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptAutoJoin skip blacklisted -> status=" 10154dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 10164dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) + " rssi=(" 10174dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + "," + config.visibility.rssi5 10184dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ") num=(" + config.visibility.num24 10194dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + "," + config.visibility.num5 + ")"); 10204dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 102127355a942653264388e909a4276196ee63e57811vandwalle continue; 102227355a942653264388e909a4276196ee63e57811vandwalle } 1023f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (config.networkId == currentNetId) { 1024ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 102521bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle logDbg("attemptAutoJoin skip current candidate " 102621bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle + Integer.toString(currentNetId) 1027ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle + " key " + config.configKey(true)); 1028ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1029f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle continue; 1030f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1031f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 103221bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle if (lastSelectedConfiguration == null || 103321bc54cb37a0085b1c909cb4d55ebb12a2facefbvandwalle !config.configKey().equals(lastSelectedConfiguration)) { 10348c9088d11880553458f09377cc60d6eb7e66747bvandwalle //don't try to autojoin a network that is too far 10358c9088d11880553458f09377cc60d6eb7e66747bvandwalle if (config.visibility == null) { 10368c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 10378c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 103827355a942653264388e909a4276196ee63e57811vandwalle if (config.visibility.rssi5 < WifiConfiguration.INITIAL_AUTO_JOIN_ATTEMPT_MIN_5 1039c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle && config.visibility.rssi24 1040c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle < WifiConfiguration.INITIAL_AUTO_JOIN_ATTEMPT_MIN_24) { 10414dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (DBG) { 10424dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle logDbg("attemptAutoJoin gskip due to low visibility -> status=" 10434dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.autoJoinStatus 10444dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " key " + config.configKey(true) + " rssi=" 10454dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.visibility.rssi24 + ", " + config.visibility.rssi5 10464dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " num=" + config.visibility.num24 10474dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + ", " + config.visibility.num5); 10484dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 10498c9088d11880553458f09377cc60d6eb7e66747bvandwalle continue; 10508c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 10518c9088d11880553458f09377cc60d6eb7e66747bvandwalle } 10528c9088d11880553458f09377cc60d6eb7e66747bvandwalle 1053ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle if (DBG) { 1054c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle logDbg("attemptAutoJoin trying candidate id=" 1055c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + Integer.toString(config.networkId) + " " 10564dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + config.SSID + " key " + config.configKey(true) 10574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " status=" + config.autoJoinStatus); 1058ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle } 1059f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1060f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate == null) { 1061f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1062f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1063f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (VDBG) { 1064453aee50caf7e332e77ab3d995d7c87a958e4fd4vandwalle logDbg("attemptAutoJoin will compare candidate " + candidate.configKey() 10654dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle + " with " + config.configKey()); 1066f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1067f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1068f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int order = compareWifiConfigurations(candidate, config); 1069f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (order > 0) { 1070f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //ascending : candidate < config 1071f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = config; 1072f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1073f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1074f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1075f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1076f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle /* now, go thru scan result to try finding a better Herrevad network */ 1077f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (mNetworkScoreCache != null) { 1078f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi5 = WifiConfiguration.INVALID_RSSI; 1079f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int rssi24 = WifiConfiguration.INVALID_RSSI; 1080f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle WifiConfiguration.Visibility visibility; 1081f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (candidate != null) { 1082f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi5 = candidate.visibility.rssi5; 1083f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle rssi24 = candidate.visibility.rssi24; 1084f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1085f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1086f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //get current date 1087b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle long now_ms = System.currentTimeMillis(); 1088f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1089f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (rssi5 < -60 && rssi24 < -70) { 1090f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle for (ScanResult result : scanResultCache.values()) { 1091f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((now_ms - result.seen) < 3000) { 1092f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle int score = mNetworkScoreCache.getNetworkScore(result); 1093f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (score > 0) { 1094f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // try any arbitrary formula for now, adding apple and oranges, 1095f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // i.e. adding network score and "dBm over noise" 10964dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle if (result.is24GHz()) { 1097f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.level + score) > (rssi24 -40)) { 1098f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // force it as open, TBD should we otherwise verify that this 1099f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // BSSID only supports open?? 1100f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.capabilities = ""; 1101f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1102f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //switch to this scan result 1103f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = 1104c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle mWifiConfigStore.wifiConfigurationFromScanResult(result); 1105f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate.ephemeral = true; 1106f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1107f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } else { 1108f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if ((result.level + score) > (rssi5 -30)) { 1109f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // force it as open, TBD should we otherwise verify that this 1110f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle // BSSID only supports open?? 1111f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle result.capabilities = ""; 1112f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1113f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle //switch to this scan result 1114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate = 1115c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle mWifiConfigStore.wifiConfigurationFromScanResult(result); 1116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle candidate.ephemeral = true; 1117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1119f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1120f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1121f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1122f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1123f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1124b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle 1125b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle /* if candidate is found, check the state of the connection so as 11264dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle to decide if we should be acting on this candidate and switching over */ 1127b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle int networkDelta = compareNetwork(candidate); 1128b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle if (DBG && candidate != null) { 1129b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle logDbg("attemptAutoJoin compare SSID candidate : delta=" 1130b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + Integer.toString(networkDelta) + " " 1131b57df70bdf17ba45ef4d18b11414cb24dcbe1fb9vandwalle + candidate.configKey() 1132c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle + " linked=" + (currentConfiguration != null 1133c6f06c628ee3583b60ff31a7da442e0ac7b26d97vandwalle && currentConfiguration.isLinked(candidate))); 1134b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 11354dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1136b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle /* ASK WifiStateMachine permission to switch: 1137b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle for instance, 1138b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if user is currently streaming voice traffic, 1139b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle then don’t switch regardless of the delta 1140b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle */ 1141b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mWifiStateMachine.shouldSwitchNetwork(networkDelta)) { 1142b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (mStaStaSupported) { 1143b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("mStaStaSupported --> error do nothing now "); 1144b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1145b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (currentConfiguration != null && currentConfiguration.isLinked(candidate)) { 1146b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_EXTENDED_ROAMING; 1147b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } else { 1148b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_OUT_OF_NETWORK_ROAMING; 1149b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1150b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1151b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto connect with netId " 1152b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(candidate.networkId) 1153b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " to " + candidate.configKey()); 1154b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1155b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, 1156b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle candidate.networkId, networkSwitchType, candidate); 11574dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle } 1158b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 11594dc6f3a322806b25d50039614cde1b94fe91ab17vandwalle 1160b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (networkSwitchType == AUTO_JOIN_IDLE) { 1161b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle //attempt same WifiConfiguration roaming 1162b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle ScanResult roamCandidate = attemptRoam(currentConfiguration, 3000); 1163b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (roamCandidate != null) { 1164b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (DBG) { 1165b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle logDbg("AutoJoin auto roam with netId " 1166b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + Integer.toString(currentConfiguration.networkId) 1167b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " " + currentConfiguration.configKey() + " to BSSID=" 1168b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + roamCandidate.BSSID + " freq=" + roamCandidate.frequency 1169b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle + " RSSI=" + roamCandidate.frequency); 1170b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle } 1171b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle networkSwitchType = AUTO_JOIN_ROAMING; 1172b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_ROAM, 1173b07da189850a4bfa268f8ab9be7867935eb2ecb5vandwalle currentConfiguration.networkId, 1, roamCandidate); 1174f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1175f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1176b97e66604f472f67c233bb8f8d9630bb36131e2cvandwalle if (VDBG) logDbg("Done attemptAutoJoin status=" + Integer.toString(networkSwitchType)); 1177f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 1178f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle} 1179f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 1180