Android -- 無線網路配置資訊的管理者WifiConfigStore簡介
阿新 • • 發佈:2019-02-01
- 從wp_s讀取儲存的網路配置列表,並儲存到mConfiguredNetworks中
- 呼叫readIpAndProxyConfigurations()方法,從ipconfig.txt中讀取儲存的IpConfiguration物件,更新到mConfiguredNetworks儲存的各WifiConfiguration物件中
- 呼叫mConfiguredNetworks()方法,從/misc/wifi/networkHistory.txt檔案中讀取儲存的資訊,更新到mConfiguredNetworks儲存的各WifiConfiguration物件中
PS:
從原生註釋中,我們得知這個變數控制了當一個網路獲取IP失敗時,之後會繼續重試的次數;如果值定義為9,那麼實際的重連次數將是9+1,為10。 如果我們有定製這個值,那麼重連次數將以我們自定義配置的值為準:/** * The maximum number of times we will retry a connection to an access point * for which we have failed in acquiring an IP address from DHCP. A value of * N means that we will make N+1 connection attempts in all. * <p> * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default * value if a Settings value is not present. */ private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
我們可以配置Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT這個欄位值來定製這部分:int WifiConfigStore::getMaxDhcpRetries() { return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT, DEFAULT_MAX_DHCP_RETRIES); }
/**
* The maximum number of times we will retry a connection to an access
* point for which we have failed in acquiring an IP address from DHCP.
* A value of N means that we will make N+1 connection attempts in all.
*/
public static final String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
getMaxDhcpRetries()在WifiConfigStore中只在handleSSIDStateChange()函式中有使用:void handleSSIDStateChange(int netId, boolean enabled, String message, String BSSID) {
WifiConfiguration config = mConfiguredNetworks.get(netId);
if (config != null) {
if (enabled) {
loge("Ignoring SSID re-enabled from supplicant: " + config.configKey() +
" had autoJoinStatus=" + Integer.toString(config.autoJoinStatus)
+ " self added " + config.selfAdded + " ephemeral " + config.ephemeral);
//We should not re-enable the BSSID based on Supplicant reanable.
// Framework will re-enable it after its own blacklist timer expires
} else {
loge("SSID temp disabled for " + config.configKey() +
" had autoJoinStatus=" + Integer.toString(config.autoJoinStatus)
+ " self added " + config.selfAdded + " ephemeral " + config.ephemeral);
if (message != null) {
loge(" message=" + message);
}
if (config.selfAdded && config.lastConnected == 0) {
// This is a network we self added, and we never succeeded,
// the user did not create this network and never entered its credentials,
// so we want to be very aggressive in disabling it completely.
removeConfigAndSendBroadcastIfNeeded(config.networkId);
} else {
if (message != null) {
if (message.contains("no identity")) {
config.setAutoJoinStatus(
WifiConfiguration.AUTO_JOIN_DISABLED_NO_CREDENTIALS);
if (DBG) {
loge("no identity blacklisted " + config.configKey() + " to "
+ Integer.toString(config.autoJoinStatus));
}
} else if (message.contains("WRONG_KEY")
|| message.contains("AUTH_FAILED")) {
// This configuration has received an auth failure, so disable it
// temporarily because we don't want auto-join to try it out.
// this network may be re-enabled by the "usual"
// enableAllNetwork function
config.numAuthFailures++;
if (config.numAuthFailures > maxAuthErrorsToBlacklist) {
config.setAutoJoinStatus
(WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE);
disableNetwork(netId,
WifiConfiguration.DISABLED_AUTH_FAILURE);
loge("Authentication failure, blacklist " + config.configKey() + " "
+ Integer.toString(config.networkId)
+ " num failures " + config.numAuthFailures);
}
} else if (message.contains("DHCP FAILURE")) {
config.numIpConfigFailures++;
config.lastConnectionFailure = System.currentTimeMillis();
int maxRetries = getMaxDhcpRetries();
// maxRetries == 0 means keep trying forever
if (maxRetries > 0 && config.numIpConfigFailures > maxRetries) {
/**
* If we've exceeded the maximum number of retries for DHCP
* to a given network, disable the network
*/
config.setAutoJoinStatus
(WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE);
disableNetwork(netId, WifiConfiguration.DISABLED_DHCP_FAILURE);
loge("DHCP failure, blacklist " + config.configKey() + " "
+ Integer.toString(config.networkId)
+ " num failures " + config.numIpConfigFailures);
}
// Also blacklist the BSSId if we find it
ScanResult result = null;
String bssidDbg = "";
if (getScanDetailCache(config) != null && BSSID != null) {
result = getScanDetailCache(config).get(BSSID);
}
if (result != null) {
result.numIpConfigFailures ++;
bssidDbg = BSSID + " ipfail=" + result.numIpConfigFailures;
if (result.numIpConfigFailures > 3) {
// Tell supplicant to stop trying this BSSID
mWifiNative.addToBlacklist(BSSID);
result.setAutoJoinStatus(ScanResult.AUTO_JOIN_DISABLED);
}
}
if (DBG) {
loge("blacklisted " + config.configKey() + " to "
+ config.autoJoinStatus
+ " due to IP config failures, count="
+ config.numIpConfigFailures
+ " disableReason=" + config.disableReason
+ " " + bssidDbg);
}
} else if (message.contains("CONN_FAILED")) {
config.numConnectionFailures++;
if (config.numConnectionFailures > maxConnectionErrorsToBlacklist) {
config.setAutoJoinStatus
(WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE);
disableNetwork(netId,
WifiConfiguration.DISABLED_ASSOCIATION_REJECT);
loge("Connection failure, blacklist " + config.configKey() + " "
+ config.networkId
+ " num failures " + config.numConnectionFailures);
}
}
message.replace("\n", "");
message.replace("\r", "");
config.lastFailure = message;
}
}
}
}
}
在WifiStateMachine中,如果一個網路DHCP獲取IP失敗、或STATIC IP配置失敗、或網路的配置資訊丟失,都會間接呼叫到handleSSIDStateChange()函式,在配置的次數內嘗試網路重連。我們看一個例子: private void WifiStateMachine::handleIpConfigurationLost() {
mWifiInfo.setInetAddress(null);
mWifiInfo.setMeteredHint(false);
mWifiConfigStore.handleSSIDStateChange(mLastNetworkId, false,
"DHCP FAILURE", mWifiInfo.getBSSID());//函式呼叫
/* DHCP times out after about 30 seconds, we do a
* disconnect thru supplicant, we will let autojoin retry connecting to the network
*/
mWifiNative.disconnect();
}
這裡呼叫時,netId為當前使用的網路的netId,用以在WifiConfigStore獲取到對應的WifiConfiguration,enabled為false,message為DHCP_FALURE;對照handleSSIDStateChange()實現,我們可以分析得出: