前言: 之前在(五十五)Android O 连接WiFi AP流程梳理 梳理连接流程梳理到SupplicantStaNetworkHal 然后没梳理的下去,现在继续梳理下。
相关梳理:
1)(九十三) Android O 连接WiFi AP流程梳理续——保存网络
2) (九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程
1. 前期准备
1.小米 mix2 Android O抓取连接WiFi期间的log:
09-01 21:09:27.991 1561 2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:27.993 1561 2457 D SupplicantStaIfaceHal: ISupplicantStaIface.listNetworks succeeded
09-01 21:09:27.993 2379 2379 D wpa_supplicant: Deregistering network from hidl control: 0
09-01 21:09:27.994 1561 1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkRemoved received
09-01 21:09:27.995 1561 2460 D WifiHandler.WifiScanningService: Received message=159773d sendingUid=1000
09-01 21:09:27.995 1561 2457 D SupplicantStaIfaceHal: ISupplicantStaIface.removeNetwork succeeded
09-01 21:09:27.995 1561 2457 I SupplicantStaIfaceHal: addSupplicantStaNetwork via HIDL
09-01 21:09:27.995 1561 2460 D WifiScanningService: replySucceeded recvdMessage=159773
09-01 21:09:27.995 2379 2379 D wpa_supplicant: Registering network to hidl control: 0
09-01 21:09:27.995 1561 1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkAdded received
09-01 21:09:27.996 1561 2457 D SupplicantStaIfaceHal: ISupplicantStaIface.addNetwork succeeded
09-01 21:09:27.996 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setSsid succeeded
09-01 21:09:27.996 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setBssid succeeded
09-01 21:09:28.002 1561 14441 D WifiService: getConfiguredNetworks uid=1000
09-01 21:09:28.002 1561 14441 D WifiAsyncChannel.WifiService: sendMessageSynchronously.send message=131131
09-01 21:09:28.016 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPskPassphrase succeeded
09-01 21:09:28.016 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setScanSsid succeeded
09-01 21:09:28.016 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setRequirePmf succeeded
09-01 21:09:28.017 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setKeyMgmt succeeded
09-01 21:09:28.017 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setProto succeeded
09-01 21:09:28.018 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setAuthAlg succeeded
09-01 21:09:28.018 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setGroupCipher succeeded
09-01 21:09:28.019 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPairwiseCipher succeeded
09-01 21:09:28.019 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setIdStr succeeded
09-01 21:09:28.020 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.registerCallback succeeded
09-01 21:09:28.020 2379 2379 E wpa_supplicant: eap_proxy: eap_proxy_notify_config
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: Scan results matching the currently selected network
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 0: 20:6b:e7:93:84:f9 ssid='jiatai 5G' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x511
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wpa_supplicant_ssid_bss_match : wapi is null
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: 0: 20:6b:e7:93:84:f9 freq=5765 level=-45 snr=47 est_throughput=390001
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 1: e4:ea:83:03:94:dc ssid='CMCC-RDNL-5G' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x11
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 2: d8:c8:e9:1d:5e:b0 ssid='@PHICOMM_A0_5G' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x31
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 3: 20:6b:e7:93:84:f7 ssid='jiatai 2.4G' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 4: 30:fc:68:6e:89:c0 ssid='TP-LINK_89C0' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 5: d8:c8:e9:1d:5e:a8 ssid='703' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0xc11
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 6: e4:72:e2:82:12:a0 ssid='ChinaNet-xYjr' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 7: 8c:be:be:44:46:3c ssid='Xiaomi-Wan' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0xc11
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 8: e4:ea:83:03:94:d0 ssid='CMCC-RDNL' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 9: 62:01:0f:b8:2b:f2 ssid='iTV-R3rH' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 10: 08:01:0f:b8:2b:f1 ssid='ChinaNet-R3rH' wpa_ie_len=26 rsn_ie_len=0 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 11: 44:6e:e5:88:c0:bc ssid='HUAWEI-Apple' wpa_ie_len=0 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 12: ac:54:74:1f:a0:e0 ssid='CMCC-3pc7' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 13: 48:7d:2e:b1:b7:e9 ssid='TP-LINK804' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x1c11
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 14: 8c:be:be:44:46:3d ssid='Xiaomi-Wan_5G' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x31
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 15: 1c:60:de:3d:c6:70 ssid='modenggongyu' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x31
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 16: 88:25:93:45:2c:3f ssid='303' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 17: 5c:09:79:25:f1:58 ssid='ChinaNet-YPpp' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: Selecting BSS from priority group 0
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: 0: 20:6b:e7:93:84:f9 ssid='jiatai 5G' wpa_ie_len=22 rsn_ie_len=20 caps=0x511 level=-45 freq=5765
09-01 21:09:28.020 2379 2379 D wpa_supplicant: 0: 20:6b:e7:93:84:f9 ssid='jiatai 5G' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x511
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wpa_supplicant_ssid_bss_match : wapi is null
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: selected based on RSN IE
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: selected BSS 20:6b:e7:93:84:f9 ssid='jiatai 5G'
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: Considering connect request: reassociate: 1 selected: 20:6b:e7:93:84:f9 bssid: 00:00:00:00:00:00 pending: 00:00:00:00:00:00 wpa_state: DISCONNECTED ssid=0x76a18b5c00 current_ssid=0x76a18b5c00
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: Request association with 20:6b:e7:93:84:f9
09-01 21:09:28.020 2379 2379 D wpa_supplicant: TDLS: TDLS is allowed in the target BSS
09-01 21:09:28.020 2379 2379 D wpa_supplicant: TDLS: TDLS channel switch allowed in the target BSS
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: No ongoing scan/p2p-scan found to abort
09-01 21:09:28.020 2379 2379 D wpa_supplicant: wlan0: Add radio work 'connect'@0x76a1830540
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: First radio work item in the queue - schedule start immediately
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: Starting radio work 'connect'@0x76a1830540 after 0.000085 second wait
09-01 21:09:28.021 2379 2379 I wpa_supplicant: wlan0: Trying to associate with SSID 'jiatai 5G'
09-01 21:09:28.021 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.select succeeded
09-01 21:09:28.021 2379 2379 I wpa_supplicant: wlan0: Trying to associate with SSID 'jiatai 5G'
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: Cancelling scan request
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: WPA: clearing own WPA/RSN IE
09-01 21:09:28.021 2379 2379 D wpa_supplicant: RSN: PMKSA cache search - network_ctx=0x76a18b5c00 try_opportunistic=0
09-01 21:09:28.021 2379 2379 D wpa_supplicant: RSN: Search for BSSID 20:6b:e7:93:84:f9
09-01 21:09:28.021 2379 2379 D wpa_supplicant: RSN: No PMKSA cache entry found
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: RSN: using IEEE 802.11i/D9.0
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: WPA: Selected cipher suites: group 16 pairwise 16 key_mgmt 2 proto 2
09-01 21:09:28.021 2379 2379 D wpa_supplicant: WPA: set AP WPA IE - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 04 01 00 00 50 f2 04 01 00 00 50 f2 02
09-01 21:09:28.021 1561 2457 D SupplicantStateTracker: DefaultState{ when=-32ms what=151553 arg1=16 target=com.android.internal.util.StateMachine$SmHandler }
09-01 21:09:28.021 2379 2379 D wpa_supplicant: WPA: set AP RSN IE - hexdump(len=22): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 00 00
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: WPA: using GTK CCMP
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: WPA: using PTK CCMP
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: WPA: using KEY_MGMT WPA-PSK
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: WPA: not using MGMT group cipher
09-01 21:09:28.021 2379 2379 D wpa_supplicant: WPA: Set own WPA IE default - hexdump(len=22): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 00 00
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: Automatic auth_alg selection: 0x1
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: Overriding auth_alg selection: 0x1
09-01 21:09:28.021 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021 2379 2379 D wpa_supplicant: Added supported operating classes IE - hexdump(len=18): 3b 10 7c 51 53 54 73 74 75 76 77 78 7c 7d 7e 7f 80 82
09-01 21:09:28.021 2379 2379 D wpa_supplicant: wlan0: State: DISCONNECTED -> ASSOCIATING
2.(五十五)Android O 连接WiFi AP流程梳理 之前梳理的WiFi连接的时序图
2.流程梳理
2.1 WifiSettings
/* package */ void submit(WifiConfigController configController) {
final WifiConfiguration config = configController.getConfig();
if (config == null) {
if (mSelectedAccessPoint != null
&& mSelectedAccessPoint.isSaved()) {
connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */);
}
} else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) {
mWifiManager.save(config, mSaveListener);
} else {
mWifiManager.save(config, mSaveListener);
if (mSelectedAccessPoint != null) { // Not an "Add network"
connect(config, false /* isSavedNetwork */);
}
}
mWifiTracker.resumeScanning();
}
protected void connect(final WifiConfiguration config, boolean isSavedNetwork) {
// Log subtype if configuration is a saved network.
mMetricsFeatureProvider.action(getActivity(), MetricsEvent.ACTION_WIFI_CONNECT,
isSavedNetwork);
mWifiManager.connect(config, mConnectListener);
mClickedConnect = true;
}
2.2 WifiManager
/**
* Connect to a network with the given configuration. The network also
* gets added to the list of configured networks for the foreground user.
*
* For a new network, this function is used instead of a
* sequence of addNetwork(), enableNetwork(), saveConfiguration() and
* reconnect()
*
* @param config the set of variables that describe the configuration,
* contained in a {@link WifiConfiguration} object.
* @param listener for callbacks on success or failure. Can be null.
* @throws IllegalStateException if the WifiManager instance needs to be
* initialized again
*
* @hide
*/
@SystemApi
public void connect(WifiConfiguration config, ActionListener listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
// Use INVALID_NETWORK_ID for arg1 when passing a config object
// arg1 is used to pass network id when the network already exists
getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
putListener(listener), config);
}
2.3 WifiServiceImpl
case WifiManager.CONNECT_NETWORK: {
if (checkChangePermissionAndReplyIfNotAuthorized(
msg, WifiManager.CONNECT_NETWORK_FAILED)) {
WifiConfiguration config = (WifiConfiguration) msg.obj;
int networkId = msg.arg1;
Slog.d(TAG, "CONNECT "
+ " nid=" + Integer.toString(networkId)
+ " uid=" + msg.sendingUid
+ " name="
+ mContext.getPackageManager().getNameForUid(msg.sendingUid));
if (config != null) {
if (DBG) Slog.d(TAG, "Connect with config " + config);
/* Command is forwarded to state machine */
mWifiStateMachine.sendMessage(Message.obtain(msg));
} else if (config == null
&& networkId != WifiConfiguration.INVALID_NETWORK_ID) {
if (DBG) Slog.d(TAG, "Connect with networkId " + networkId);
mWifiStateMachine.sendMessage(Message.obtain(msg));
} else {
Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED,
WifiManager.INVALID_ARGS);
}
}
break;
}
2.4 WifiStateMachine
case WifiManager.CONNECT_NETWORK:
/**
* The connect message can contain a network id passed as arg1 on message or
* or a config passed as obj on message.
* For a new network, a config is passed to create and connect.
* For an existing network, a network id is passed
*/
netId = message.arg1;
config = (WifiConfiguration) message.obj;
mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
boolean hasCredentialChanged = false;
// New network addition.
if (config != null) {
result = mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid);
if (!result.isSuccess()) {
loge("CONNECT_NETWORK adding/updating config=" + config + " failed");
messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
WifiManager.ERROR);
break;
}
netId = result.getNetworkId();
hasCredentialChanged = result.hasCredentialChanged();
}
if (!connectToUserSelectNetwork(
netId, message.sendingUid, hasCredentialChanged)) {
messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
WifiManager.NOT_AUTHORIZED);
break;
}
mWifiMetrics.logStaEvent(StaEvent.TYPE_CONNECT_NETWORK, config);
broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
break;
这边分为两步:
- 更新网络并获取netId和验证credential是否改变
- 连接网络
对于新添加网络hasCredentialChanged肯定是false的,刚更新config为最新的。
/**
* Initiates connection to a network specified by the user/app. This method checks if the
* requesting app holds the NETWORK_SETTINGS permission.
*
* @param netId Id network to initiate connection.
* @param uid UID of the app requesting the connection.
* @param forceReconnect Whether to force a connection even if we're connected to the same
* network currently.
*/
private boolean connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) {
logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid
+ ", forceReconnect = " + forceReconnect);
if (mWifiConfigManager.getConfiguredNetwork(netId) == null) {
loge("connectToUserSelectNetwork Invalid network Id=" + netId);
return false;
}
if (!mWifiConfigManager.enableNetwork(netId, true, uid)
|| !mWifiConfigManager.checkAndUpdateLastConnectUid(netId, uid)) {
logi("connectToUserSelectNetwork Allowing uid " + uid
+ " with insufficient permissions to connect=" + netId);
} else {
// Note user connect choice here, so that it will be considered in the next network
// selection.
mWifiConnectivityManager.setUserConnectChoice(netId);
}
if (!forceReconnect && mWifiInfo.getNetworkId() == netId) {
// We're already connected to the user specified network, don't trigger a
// reconnection unless it was forced.
logi("connectToUserSelectNetwork already connecting/connected=" + netId);
} else {
mWifiConnectivityManager.prepareForForcedConnection(netId);
startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY);
}
return true;
}
/**
* Value to set in wpa_supplicant "bssid" field when we don't want to restrict connection to
* a specific AP.
*/
public static final String SUPPLICANT_BSSID_ANY = "any";
这边有个注释比较有意思,这边会记住用户的选择,在下次网络选择的时候会考虑其中,也就是说打开WiFi时的自动连接会将用户最近一次的连接行为考虑其中,这也很合理。
/**
* Automatically connect to the network specified
*
* @param networkId ID of the network to connect to
* @param uid UID of the app triggering the connection.
* @param bssid BSSID of the network
*/
public void startConnectToNetwork(int networkId, int uid, String bssid) {
sendMessage(CMD_START_CONNECT, networkId, uid, bssid);
}
ConnectModeState会处理CMD_START_CONNECT 消息
case CMD_START_CONNECT:
/* connect command coming from auto-join */
netId = message.arg1;
int uid = message.arg2;
bssid = (String) message.obj;
synchronized (mWifiReqCountLock) {
if (!hasConnectionRequests()) {
if (mNetworkAgent == null) {
loge("CMD_START_CONNECT but no requests and not connected,"
+ " bailing");
break;
} else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
loge("CMD_START_CONNECT but no requests and connected, but app "
+ "does not have sufficient permissions, bailing");
break;
}
}
}
config = mWifiConfigManager.getConfiguredNetworkWithPassword(netId);
logd("CMD_START_CONNECT sup state "
+ mSupplicantStateTracker.getSupplicantStateName()
+ " my state " + getCurrentState().getName()
+ " nid=" + Integer.toString(netId)
+ " roam=" + Boolean.toString(mIsAutoRoaming));
if (config == null) {
loge("CMD_START_CONNECT and no config, bail out...");
break;
}
mTargetNetworkId = netId;
setTargetBssid(config, bssid);
reportConnectionAttemptStart(config, mTargetRoamBSSID,
WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);
if (mWifiNative.connectToNetwork(config)) {
mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT, config);
lastConnectAttemptTimestamp = mClock.getWallClockMillis();
targetWificonfiguration = config;
mIsAutoRoaming = false;
if (isLinkDebouncing()) {
transitionTo(mRoamingState);
} else if (getCurrentState() != mDisconnectedState) {
transitionTo(mDisconnectingState);
}
} else {
loge("CMD_START_CONNECT Failed to start connection to network " + config);
reportConnectionAttemptEnd(
WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED,
WifiMetricsProto.ConnectionEvent.HLF_NONE);
replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
WifiManager.ERROR);
break;
}
break;
2.5 WifiNative
/**
* Add the provided network configuration to wpa_supplicant and initiate connection to it.
* This method does the following:
* 1. Abort any ongoing scan to unblock the connection request.
* 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
* 3. Add a new network to wpa_supplicant.
* 4. Save the provided configuration to wpa_supplicant.
* 5. Select the new network in wpa_supplicant.
* 6. Triggers reconnect command to wpa_supplicant.
*
* @param configuration WifiConfiguration parameters for the provided network.
* @return {@code true} if it succeeds, {@code false} otherwise
*/
public boolean connectToNetwork(WifiConfiguration configuration) {
// Abort ongoing scan before connect() to unblock connection request.
mWificondControl.abortScan();
return mSupplicantStaIfaceHal.connectToNetwork(configuration);
}
如注释所示,这个方法做了6件事:
1. 中止任何正在进行的扫描来不阻塞连接请求
2.删除wpa_supplicant中的任何现有网络(这会隐式触发断开连接)
3.在wpa_supplicant中添加一个新的网络
4.在wpa_supplicant中保存提供的configuration
5.在wpa_supplicant中选择新的网络
6.触发wpa_supplicant 的重新连接命令
2.6 SupplicantStaIfaceHal
/**
* Add the provided network configuration to wpa_supplicant and initiate connection to it.
* This method does the following:
* 1. If |config| is different to the current supplicant network, removes all supplicant
* networks and saves |config|.
* 2. Select the new network in wpa_supplicant.
*
* @param config WifiConfiguration parameters for the provided network.
* @return {@code true} if it succeeds, {@code false} otherwise
*/
public boolean connectToNetwork(@NonNull WifiConfiguration config) {
synchronized (mLock) {
logd("connectToNetwork " + config.configKey());
if (WifiConfigurationUtil.isSameNetwork(config, mCurrentNetworkLocalConfig)) {
logd("Network is already saved, will not trigger remove and add operation.");
} else {
mCurrentNetworkRemoteHandle = null;
mCurrentNetworkLocalConfig = null;
if (!removeAllNetworks()) {
loge("Failed to remove existing networks");
return false;
}
Pair<SupplicantStaNetworkHal, WifiConfiguration> pair =
addNetworkAndSaveConfig(config);
if (pair == null) {
loge("Failed to add/save network configuration: " + config.configKey());
return false;
}
mCurrentNetworkRemoteHandle = pair.first;
mCurrentNetworkLocalConfig = pair.second;
}
if (!mCurrentNetworkRemoteHandle.select()) {
loge("Failed to select network configuration: " + config.configKey());
return false;
}
return true;
}
}
这边连接网络涉及两步:添加网络并保存配置以及选择网络
相关log
09-01 21:09:27.991 936 936 W wificond: Scan is not started. Ignore abort request
09-01 21:09:27.991 1561 2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:27.993 1561 2457 D SupplicantStaIfaceHal: ISupplicantStaIface.listNetworks succeeded
09-01 21:09:27.993 2379 2379 D wpa_supplicant: Deregistering network from hidl control: 0
09-01 21:09:27.994 1561 1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkRemoved received
09-01 21:09:27.995 1561 2460 D WifiHandler.WifiScanningService: Received message=159773d sendingUid=1000
09-01 21:09:27.995 1561 2457 D SupplicantStaIfaceHal: ISupplicantStaIface.removeNetwork succeeded
09-01 21:09:27.995 1561 2457 I SupplicantStaIfaceHal: addSupplicantStaNetwork via HIDL
09-01 21:09:27.995 1561 2460 D WifiScanningService: replySucceeded recvdMessage=159773
09-01 21:09:27.995 2379 2379 D wpa_supplicant: Registering network to hidl control: 0
09-01 21:09:27.995 1561 1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkAdded received
09-01 21:09:27.996 1561 2457 D SupplicantStaIfaceHal: ISupplicantStaIface.addNetwork succeeded
09-01 21:09:27.996 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setSsid succeeded
09-01 21:09:27.996 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setBssid succeeded
09-01 21:09:28.002 1561 14441 D WifiService: getConfiguredNetworks uid=1000
09-01 21:09:28.002 1561 14441 D WifiAsyncChannel.WifiService: sendMessageSynchronously.send message=131131
09-01 21:09:28.016 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPskPassphrase succeeded
09-01 21:09:28.016 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setScanSsid succeeded
09-01 21:09:28.016 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setRequirePmf succeeded
09-01 21:09:28.017 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setKeyMgmt succeeded
09-01 21:09:28.017 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setProto succeeded
09-01 21:09:28.018 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setAuthAlg succeeded
09-01 21:09:28.018 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setGroupCipher succeeded
09-01 21:09:28.019 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPairwiseCipher succeeded
09-01 21:09:28.019 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setIdStr succeeded
09-01 21:09:28.020 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.registerCallback succeeded
2.6.1 addNetworkAndSaveConfig
/**
* Add a network configuration to wpa_supplicant.
*
* @param config Config corresponding to the network.
* @return a Pair object including SupplicantStaNetworkHal and WifiConfiguration objects
* for the current network.
*/
private Pair<SupplicantStaNetworkHal, WifiConfiguration>
addNetworkAndSaveConfig(WifiConfiguration config) {
synchronized (mLock) {
logi("addSupplicantStaNetwork via HIDL");
if (config == null) {
loge("Cannot add NULL network!");
return null;
}
SupplicantStaNetworkHal network = addNetwork();
if (network == null) {
loge("Failed to add a network!");
return null;
}
boolean saveSuccess = false;
try {
saveSuccess = network.saveWifiConfiguration(config);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Exception while saving config params: " + config, e);
}
if (!saveSuccess) {
loge("Failed to save variables for: " + config.configKey());
if (!removeAllNetworks()) {
loge("Failed to remove all networks on failure.");
}
return null;
}
return new Pair(network, new WifiConfiguration(config));
}
}
/**
* Adds a new network.
*
* @return The ISupplicantNetwork object for the new network, or null if the call fails
*/
private SupplicantStaNetworkHal addNetwork() {
synchronized (mLock) {
final String methodStr = "addNetwork";
if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
try {
mISupplicantStaIface.addNetwork((SupplicantStatus status,
ISupplicantNetwork network) -> {
if (checkStatusAndLogFailure(status, methodStr)) {
newNetwork.value = network;
}
});
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
}
if (newNetwork.value != null) {
return getStaNetworkMockable(
ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
} else {
return null;
}
}
}
mISupplicantStaIface 在 八十八)Android O WiFi启动流程梳理续——connectToSupplicant 梳理过,是连接supplicant成功后framework保留下来的服务器对象即ISupplicantStaIface应该是对应sta_iface.cpp的引用
external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/sta_iface.cpp
Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&StaIface::addNetworkInternal, _hidl_cb);
}
std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
StaIface::addNetworkInternal()
{
android::sp<ISupplicantStaNetwork> network;
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
if (!ssid) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
}
HidlManager *hidl_manager = HidlManager::getInstance();
if (!hidl_manager ||
hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
wpa_s->ifname, ssid->id, &network)) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
}
return {{SupplicantStatusCode::SUCCESS, ""}, network};
}
/**
* Retrieve the underlying |wpa_supplicant| struct
* pointer for this iface.
* If the underlying iface is removed, then all RPC method calls on this object
* will return failure.
*/
wpa_supplicant *StaIface::retrieveIfacePtr()
{
return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
}
wpa_supplicant.c
/**
* wpa_supplicant_add_network - Add a new network
* @wpa_s: wpa_supplicant structure for a network interface
* Returns: The new network configuration or %NULL if operation failed
*
* This function performs the following operations:
* 1. Adds a new network.
* 2. Send network addition notification.
* 3. Marks the network disabled.
* 4. Set network default parameters.
*/
struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
{
struct wpa_ssid *ssid;
ssid = wpa_config_add_network(wpa_s->conf);
if (!ssid)
return NULL;
wpas_notify_network_added(wpa_s, ssid);
ssid->disabled = 1;
wpa_config_set_network_defaults(ssid);
return ssid;
}
config.c
/**
* wpa_config_add_network - Add a new network with empty configuration
* @config: Configuration data from wpa_config_read()
* Returns: The new network configuration or %NULL if operation failed
*/
struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
{
int id;
struct wpa_ssid *ssid, *last = NULL;
id = -1;
ssid = config->ssid;
while (ssid) {
if (ssid->id > id)
id = ssid->id;
last = ssid;
ssid = ssid->next;
}
id++;
ssid = os_zalloc(sizeof(*ssid));
if (ssid == NULL)
return NULL;
ssid->id = id;
dl_list_init(&ssid->psk_list);
if (last)
last->next = ssid;
else
config->ssid = ssid;
wpa_config_update_prio_list(config);
return ssid;
}
遍历ssid,找到最大的id,然后加1作为新添加网络的id。说到底就是在结构体数组后面加一个新的,没有就自己当第一个。
另外这个方法也很关键
wpas_notify_network_added(wpa_s, ssid);
notify.c
void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
if (wpa_s->p2p_mgmt)
return;
/*
* Networks objects created during any P2P activities should not be
* exposed out. They might/will confuse certain non-P2P aware
* applications since these network objects won't behave like
* regular ones.
*/
if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) {
wpas_dbus_register_network(wpa_s, ssid);
wpas_hidl_register_network(wpa_s, ssid);
}
}
hidl.cpp
int wpas_hidl_register_network(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
{
if (!wpa_s || !wpa_s->global->hidl || !ssid)
return 1;
wpa_printf(
MSG_DEBUG, "Registering network to hidl control: %d", ssid->id);
HidlManager *hidl_manager = HidlManager::getInstance();
if (!hidl_manager)
return 1;
return hidl_manager->registerNetwork(wpa_s, ssid);
}
hidl_manager.cpp
/**
* Register a network to hidl manager.
*
* @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
* the network is added.
* @param ssid |wpa_ssid| struct corresponding to the network being added.
*
* @return 0 on success, 1 on failure.
*/
int HidlManager::registerNetwork(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
{
if (!wpa_s || !ssid)
return 1;
// Generate the key to be used to lookup the network.
const std::string network_key =
getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
if (isP2pIface(wpa_s)) {
if (addHidlObjectToMap<P2pNetwork>(
network_key,
new P2pNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
p2p_network_object_map_)) {
wpa_printf(
MSG_ERROR,
"Failed to register P2P network with HIDL "
"control: %d",
ssid->id);
return 1;
}
p2p_network_callbacks_map_[network_key] =
std::vector<android::sp<ISupplicantP2pNetworkCallback>>();
// Invoke the |onNetworkAdded| method on all registered
// callbacks.
callWithEachP2pIfaceCallback(
wpa_s->ifname,
std::bind(
&ISupplicantP2pIfaceCallback::onNetworkAdded,
std::placeholders::_1, ssid->id));
} else {
if (addHidlObjectToMap<StaNetwork>(
network_key,
new StaNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
sta_network_object_map_)) {
wpa_printf(
MSG_ERROR,
"Failed to register STA network with HIDL "
"control: %d",
ssid->id);
return 1;
}
sta_network_callbacks_map_[network_key] =
std::vector<android::sp<ISupplicantStaNetworkCallback>>();
// Invoke the |onNetworkAdded| method on all registered
// callbacks.
callWithEachStaIfaceCallback(
wpa_s->ifname,
std::bind(
&ISupplicantStaIfaceCallback::onNetworkAdded,
std::placeholders::_1, ssid->id));
}
return 0;
}
/**
* Creates a unique key for the network using the provided |ifname| and
* |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
* This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
*
* @param ifname Name of the corresponding interface.
* @param network_id ID of the corresponding network.
*/
const std::string getNetworkObjectMapKey(
const std::string &ifname, int network_id)
{
return ifname + "_" + std::to_string(network_id);
}
// Map of all the STA network specific hidl objects controlled by
// wpa_supplicant. This map is keyed in by the corresponding
// |ifname| & |network_id|.
std::map<const std::string, android::sp<StaNetwork>>
sta_network_object_map_;
这边new出一个StaNetwork对应,以network_key为key放入了sta_network_object_map_这个map中。
sta_network.h
/**
* Implementation of StaNetwork hidl object. Each unique hidl
* object is used for control operations on a specific network
* controlled by wpa_supplicant.
*/
class StaNetwork : public ISupplicantStaNetwork
{
public:
StaNetwork(
struct wpa_global* wpa_global, const char ifname[], int network_id);
~StaNetwork() override = default;
// Refer to |StaIface::invalidate()|.
一系列网络添加流程完了以后返回一个network对象给上层,这个network对象就是刚才在HidlManager中注册的StaNetwork对象。
HidlManager *hidl_manager = HidlManager::getInstance();
if (!hidl_manager ||
hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
wpa_s->ifname, ssid->id, &network)) {
return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
}
hidl_manager.cpp
/**
* Retrieve the |ISupplicantStaNetwork| hidl object reference using the provided
* ifname and network_id.
*
* @param ifname Name of the corresponding interface.
* @param network_id ID of the corresponding network.
* @param network_object Hidl reference corresponding to the network.
*
* @return 0 on success, 1 on failure.
*/
int HidlManager::getStaNetworkHidlObjectByIfnameAndNetworkId(
const std::string &ifname, int network_id,
android::sp<ISupplicantStaNetwork> *network_object)
{
if (ifname.empty() || network_id < 0 || !network_object)
return 1;
// Generate the key to be used to lookup the network.
const std::string network_key =
getNetworkObjectMapKey(ifname, network_id);
auto network_object_iter = sta_network_object_map_.find(network_key);
if (network_object_iter == sta_network_object_map_.end())
return 1;
*network_object = network_object_iter->second;
return 0;
}
之后会saveWifiConfiguration
SupplicantStaNetworkHal.java
/**
* Save an entire WifiConfiguration to wpa_supplicant via HIDL.
*
* @param config WifiConfiguration object to be saved.
* @return true if succeeds, false otherwise.
* @throws IllegalArgumentException on malformed configuration params.
*/
public boolean saveWifiConfiguration(WifiConfiguration config) {
synchronized (mLock) {
if (config == null) return false;
/** SSID */
if (config.SSID != null) {
if (!setSsid(NativeUtil.decodeSsid(config.SSID))) {
Log.e(TAG, "failed to set SSID: " + config.SSID);
return false;
}
}
/** BSSID */
String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
if (bssidStr != null) {
byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
if (!setBssid(bssid)) {
Log.e(TAG, "failed to set BSSID: " + bssidStr);
return false;
}
}
/** Pre Shared Key */
// This can either be quoted ASCII passphrase or hex string for raw psk.
if (config.preSharedKey != null) {
if (config.preSharedKey.startsWith("\"")) {
if (!setPskPassphrase(NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
Log.e(TAG, "failed to set psk passphrase");
return false;
}
} else {
if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) {
Log.e(TAG, "failed to set psk");
return false;
}
}
}
/** Wep Keys */
boolean hasSetKey = false;
if (config.wepKeys != null) {
for (int i = 0; i < config.wepKeys.length; i++) {
if (config.wepKeys[i] != null) {
if (!setWepKey(
i, NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i]))) {
Log.e(TAG, "failed to set wep_key " + i);
return false;
}
hasSetKey = true;
}
}
}
/** Wep Tx Key Idx */
if (hasSetKey) {
if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
return false;
}
}
/** HiddenSSID */
if (!setScanSsid(config.hiddenSSID)) {
Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
return false;
}
/** RequirePMF */
if (!setRequirePmf(config.requirePMF)) {
Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePMF);
return false;
}
/** Key Management Scheme */
if (config.allowedKeyManagement.cardinality() != 0) {
// Add FT flags if supported.
BitSet keyMgmtMask = addFastTransitionFlags(config.allowedKeyManagement);
if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) {
Log.e(TAG, "failed to set Key Management");
return false;
}
}
/** Security Protocol */
if (config.allowedProtocols.cardinality() != 0
&& !setProto(wifiConfigurationToSupplicantProtoMask(config.allowedProtocols))) {
Log.e(TAG, "failed to set Security Protocol");
return false;
}
/** Auth Algorithm */
if (config.allowedAuthAlgorithms.cardinality() != 0
&& !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
config.allowedAuthAlgorithms))) {
Log.e(TAG, "failed to set AuthAlgorithm");
return false;
}
/** Group Cipher */
if (config.allowedGroupCiphers.cardinality() != 0
&& !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
config.allowedGroupCiphers))) {
Log.e(TAG, "failed to set Group Cipher");
return false;
}
/** Pairwise Cipher*/
if (config.allowedPairwiseCiphers.cardinality() != 0
&& !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
config.allowedPairwiseCiphers))) {
Log.e(TAG, "failed to set PairwiseCipher");
return false;
}
/** metadata: FQDN + ConfigKey + CreatorUid */
final Map<String, String> metadata = new HashMap<String, String>();
if (config.isPasspoint()) {
metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
}
metadata.put(ID_STRING_KEY_CONFIG_KEY, config.configKey());
metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
if (!setIdStr(createNetworkExtra(metadata))) {
Log.e(TAG, "failed to set id string");
return false;
}
/** UpdateIdentifier */
if (config.updateIdentifier != null
&& !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
Log.e(TAG, "failed to set update identifier");
return false;
}
// Finish here if no EAP config to set
if (config.enterpriseConfig != null
&& config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) {
return false;
}
}
// Now that the network is configured fully, start listening for callback events.
mISupplicantStaNetworkCallback =
new SupplicantStaNetworkHalCallback(config.networkId, config.SSID);
if (!registerCallback(mISupplicantStaNetworkCallback)) {
Log.e(TAG, "Failed to register callback");
return false;
}
return true;
}
}
这边将WifiConfiguration中的各个属性复制到wpa_supplicant中去,比如ssid
/** See ISupplicantStaNetwork.hal for documentation */
private boolean setSsid(java.util.ArrayList<Byte> ssid) {
synchronized (mLock) {
final String methodStr = "setSsid";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
try {
SupplicantStatus status = mISupplicantStaNetwork.setSsid(ssid);
return checkStatusAndLogFailure(status, methodStr);
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
return false;
}
}
}
sta_network.cpp
Return<void> StaNetwork::setSsid(
const hidl_vec<uint8_t> &ssid, setSsid_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&StaNetwork::setSsidInternal, _hidl_cb, ssid);
}
SupplicantStatus StaNetwork::setSsidInternal(const std::vector<uint8_t> &ssid)
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (ssid.size() == 0 ||
ssid.size() >
static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
SSID_MAX_LEN_IN_BYTES)) {
return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
}
if (setByteArrayFieldAndResetState(
ssid.data(), ssid.size(), &(wpa_ssid->ssid),
&(wpa_ssid->ssid_len), "ssid")) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
if (wpa_ssid->passphrase) {
wpa_config_update_psk(wpa_ssid);
}
return {SupplicantStatusCode::SUCCESS, ""};
}
/**
* Helper function to set value in a string field with a corresponding length
* field in |wpa_ssid| structue instance for this network.
* This function frees any existing data in these fields.
*/
int StaNetwork::setByteArrayFieldAndResetState(
const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
size_t *to_update_field_len, const char *hexdump_prefix)
{
if (*to_update_field) {
os_free(*to_update_field);
}
*to_update_field = (uint8_t *)os_malloc(value_len);
if (!(*to_update_field)) {
return 1;
}
os_memcpy(*to_update_field, value, value_len);
*to_update_field_len = value_len;
wpa_hexdump_ascii(
MSG_MSGDUMP, hexdump_prefix, *to_update_field,
*to_update_field_len);
resetInternalStateAfterParamsUpdate();
return 0;
}
2.6.2 select
/**
* Trigger a connection to this network.
*
* @return true if it succeeds, false otherwise.
*/
public boolean select() {
synchronized (mLock) {
final String methodStr = "select";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
try {
SupplicantStatus status = mISupplicantStaNetwork.select();
return checkStatusAndLogFailure(status, methodStr);
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
return false;
}
}
}
sta_network.cpp
Return<void> StaNetwork::select(select_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&StaNetwork::selectInternal, _hidl_cb);
}
SupplicantStatus StaNetwork::selectInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (wpa_ssid->disabled == 2) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
wpa_s->scan_min_time.sec = 0;
wpa_s->scan_min_time.usec = 0;
wpa_supplicant_select_network(wpa_s, wpa_ssid);
return {SupplicantStatusCode::SUCCESS, ""};
}
/**
* wpa_supplicant_select_network - Attempt association with a network
* @wpa_s: wpa_supplicant structure for a network interface
* @ssid: wpa_ssid structure for a configured network or %NULL for any network
*/
void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
struct wpa_ssid *other_ssid;
int disconnected = 0;
if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
wpa_s->own_disconnect_req = 1;
wpa_supplicant_deauthenticate(
wpa_s, WLAN_REASON_DEAUTH_LEAVING);
disconnected = 1;
}
if (ssid)
wpas_clear_temp_disabled(wpa_s, ssid, 1);
/*
* Mark all other networks disabled or mark all networks enabled if no
* network specified.
*/
for (other_ssid = wpa_s->conf->ssid; other_ssid;
other_ssid = other_ssid->next) {
int was_disabled = other_ssid->disabled;
if (was_disabled == 2)
continue; /* do not change persistent P2P group data */
other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
if (was_disabled && !other_ssid->disabled)
wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
if (was_disabled != other_ssid->disabled)
wpas_notify_network_enabled_changed(wpa_s, other_ssid);
}
if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
wpa_s->wpa_state >= WPA_AUTHENTICATING) {
/* We are already associated with the selected network */
wpa_printf(MSG_DEBUG, "Already associated with the "
"selected network - do nothing");
return;
}
if (ssid) {
wpa_s->current_ssid = ssid;
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
wpa_s->connect_without_scan =
(ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
/*
* Don't optimize next scan freqs since a new ESS has been
* selected.
*/
os_free(wpa_s->next_scan_freqs);
wpa_s->next_scan_freqs = NULL;
} else {
wpa_s->connect_without_scan = NULL;
}
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
if (wpa_s->connect_without_scan ||
wpa_supplicant_fast_associate(wpa_s) != 1) {
wpa_s->scan_req = NORMAL_SCAN_REQ;
wpas_scan_reset_sched_scan(wpa_s);
wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
}
if (ssid)
wpas_notify_network_selected(wpa_s, ssid);
}
supplicant流程先到这里吧,不大看得懂,后续再梳理。待续
3. WifiStateMachine的状态变化
下面结合log看下连接过程中WifiStateMachine的状态变化
09-01 21:09:27.991 1561 2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:28.021 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575904 1000 0 num=13
09-01 21:09:28.022 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753291/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.022 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATING -> state= CONNECTING debouncing=false
09-01 21:09:28.023 1561 2457 D WifiStateMachine: setDetailed state, old =DISCONNECTED and new state=CONNECTING hidden=false
09-01 21:09:28.023 1561 2457 D WifiStateMachine: setDetailed state send new extra info"jiatai 5G"
09-01 21:09:28.023 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753292/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.036 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.036 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.036 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.036 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.042 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753310/1208575924 1000 0 num=13
09-01 21:09:28.042 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753311/1208575924 1000 0 num=13
09-01 21:09:28.042 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753311/1208575924 1000 0 num=13
09-01 21:09:28.042 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753311/1208575924 1000 0 num=13
09-01 21:09:28.047 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575929 1000 0 num=13
09-01 21:09:28.047 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575929 1000 0 num=13
09-01 21:09:28.047 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575929 1000 0 num=13
09-01 21:09:28.047 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575930 1000 0 num=13
09-01 21:09:28.053 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753322/1208575935 1000 0 num=13
09-01 21:09:28.053 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753322/1208575935 1000 0 num=13
09-01 21:09:28.053 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753322/1208575935 1000 0 num=13
09-01 21:09:28.054 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753323/1208575936 1000 0 num=13
09-01 21:09:28.059 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753328/1208575941 1000 0 num=13
09-01 21:09:28.060 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753329/1208575942 1000 0 num=13
09-01 21:09:28.060 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753329/1208575942 1000 0 num=13
09-01 21:09:28.060 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753329/1208575942 1000 0 num=13
09-01 21:09:28.065 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753334/1208575947 1000 0 num=13
09-01 21:09:28.065 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753334/1208575947 1000 0 num=13
09-01 21:09:28.065 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753334/1208575947 1000 0 num=13
09-01 21:09:28.066 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753335/1208575948 1000 0 num=13
09-01 21:09:28.071 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.071 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.071 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.071 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.074 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753343/1208575956 1000 0 num=13
09-01 21:09:28.075 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753344/1208575957 1000 0 num=13
09-01 21:09:28.075 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753344/1208575957 1000 0 num=13
09-01 21:09:28.075 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753344/1208575957 1000 0 num=13
09-01 21:09:28.081 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575963 1000 0 num=13
09-01 21:09:28.081 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575963 1000 0 num=13
09-01 21:09:28.081 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575963 1000 0 num=13
09-01 21:09:28.081 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575964 1000 0 num=13
09-01 21:09:28.083 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753352/1208575965 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.083 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATED -> state= CONNECTING debouncing=false
09-01 21:09:28.083 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=CONNECTING hidden=false
09-01 21:09:28.083 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753353/1208575966 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.084 1561 2457 D WifiStateMachine: DisconnectedState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.084 1561 2457 D WifiStateMachine: ConnectModeState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.084 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.084 1561 2457 D WifiStateMachine: DefaultState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.085 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753354/1208575967 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.085 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=FOUR_WAY_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.085 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=AUTHENTICATING hidden=false
09-01 21:09:28.086 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753355/1208575968 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.091 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753360/1208575973 1000 0 num=13
09-01 21:09:28.091 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753360/1208575974 1000 0 num=13
09-01 21:09:28.091 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753361/1208575974 1000 0 num=13
09-01 21:09:28.092 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753361/1208575974 1000 0 num=13
09-01 21:09:28.095 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.095 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=GROUP_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.095 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=AUTHENTICATING hidden=false
09-01 21:09:28.095 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.098 1561 2457 D WifiStateMachine: DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.098 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.098 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.098 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.104 1561 2457 D WifiStateMachine: DisconnectedState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104 1561 2457 D WifiStateMachine: ConnectModeState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104 1561 2457 D WifiStateMachine: Network connection established
09-01 21:09:28.105 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false
09-01 21:09:28.134 1561 2457 D WifiStateMachine: L2ConnectedState clearTargetBssid any key="jiatai 5G"-WPA_PSK
09-01 21:09:28.135 1561 2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK roam=false static=false
09-01 21:09:28.135 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false
先抽取如下SUPPLICANT_STATE_CHANGE_EVENT log看下
09-01 21:09:27.991 1561 2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:28.022 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753291/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.022 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATING -> state= CONNECTING debouncing=false
09-01 21:09:28.023 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753292/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.083 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753352/1208575965 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.083 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATED -> state= CONNECTING debouncing=false
09-01 21:09:28.083 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753353/1208575966 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.085 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753354/1208575967 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.085 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=FOUR_WAY_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.086 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753355/1208575968 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.095 1561 2457 D WifiStateMachine: DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.095 1561 2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=GROUP_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.095 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.143 1561 2457 D WifiStateMachine: ObtainingIpState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED
09-01 21:09:28.143 1561 2457 D WifiStateMachine: L2ConnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED
09-01 21:09:28.143 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED
状态机在连接过程中时是处于DisconnectedState状态,后续会一直收到SUPPLICANT_STATE_CHANGE_EVENT消息进行状态变更。
DisconnectedState的父状态ConnectModeState会做如下处理:
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
SupplicantState state = handleSupplicantStateChange(message);
// A driver/firmware hang can now put the interface in a down state.
// We detect the interface going down and recover from it
if (!SupplicantState.isDriverActive(state)) {
if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
handleNetworkDisconnect();
}
log("Detected an interface down, restart driver");
// Rely on the fact that this will force us into killing supplicant and then
// restart supplicant from a clean state.
transitionTo(mSupplicantStoppingState);
sendMessage(CMD_START_SUPPLICANT);
break;
}
// Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
// when authentication times out after a successful connection,
// we can figure this from the supplicant state. If supplicant
// state is DISCONNECTED, but the mNetworkInfo says we are not
// disconnected, we need to handle a disconnection
if (!isLinkDebouncing() && state == SupplicantState.DISCONNECTED &&
mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
if (mVerboseLoggingEnabled) {
log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
}
handleNetworkDisconnect();
transitionTo(mDisconnectedState);
}
// If we have COMPLETED a connection to a BSSID, start doing
// DNAv4/DNAv6 -style probing for on-link neighbors of
// interest (e.g. routers); harmless if none are configured.
if (state == SupplicantState.COMPLETED) {
mIpClient.confirmConfiguration();
}
break;
然后一直等放到状态变为SupplicantState.COMPLETED的时候,调用IpClient
public void confirmConfiguration() {
sendMessage(CMD_CONFIRM);
}
case CMD_CONFIRM:
// TODO: Possibly introduce a second type of confirmation
// that both probes (a) on-link neighbors and (b) does
// a DHCPv4 RENEW. We used to do this on Wi-Fi framework
// roams.
if (mIpReachabilityMonitor != null) {
mIpReachabilityMonitor.probeAll();
}
break;
接着在看下如下NETWORK_CONNECTION_EVENT log
09-01 21:09:28.104 1561 2457 D WifiStateMachine: DisconnectedState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104 1561 2457 D WifiStateMachine: ConnectModeState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104 1561 2457 D WifiStateMachine: Network connection established
09-01 21:09:28.104 1038 2499 I LOWI-8.5.0.3.a: [LOWI-Scan] get_intf_mode: WLAN interface type 2, err 0
09-01 21:09:28.104 2379 2379 D wpa_supplicant: EAPOL: SUPP_BE entering state IDLE
09-01 21:09:28.104 2379 2379 D wpa_supplicant: EAPOL authentication completed - result=SUCCESS
09-01 21:09:28.104 2379 2379 D wpa_supplicant: nl80211: Set rekey offload
09-01 21:09:28.104 2379 2379 D wpa_supplicant: RTM_NEWLINK: ifi_index=23 ifname=wlan0 operstate=6 linkmode=1 ifi_family=0 ifi_flags=0x11043 ([UP][RUNNING][LOWER_UP])
09-01 21:09:28.105 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false
09-01 21:09:28.122 1561 2455 I MiuiNetworkPolicy: wasConnected = false mWifiConnected = false mNetworkPriorityMode =255
09-01 21:09:28.122 2552 2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.122 4722 4722 D TrafficManageService: wifi2mobile:android.net.wifi.STATE_CHANGE
09-01 21:09:28.122 2552 2552 D StatusBar.NetworkController: slot=-10;action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.122 2650 2767 I QCNEJ/CndHalConnector: -> SND notifyRatConnectionStatusChanged(rat = 1, CONNECTING)
09-01 21:09:28.122 2552 2552 D StatusBar.NetworkController: updateNetworkName slotId=1 chosenNetType=13 mNetworkName=中国移动 mNetworkTypeName=4G
09-01 21:09:28.123 1561 2455 I MiuiNetworkPolicy: wasConnected = false mWifiConnected = false mNetworkPriorityMode =255
09-01 21:09:28.123 1561 4183 D WifiService: getWifiApEnabledState uid=1000
09-01 21:09:28.123 1561 4100 D WifiService: getConnectionInfo uid=1000
09-01 21:09:28.124 1088 1088 E Parcel : Reading a NULL string not supported here.
09-01 21:09:28.124 1088 1088 E Parcel : Reading a NULL string not supported here.
09-01 21:09:28.125 1561 14441 D WifiService: getWifiApEnabledState uid=1000
09-01 21:09:28.125 1088 1088 E Parcel : Reading a NULL string not supported here.
09-01 21:09:28.125 1088 1088 E Parcel : Reading a NULL string not supported here.
09-01 21:09:28.124 1561 4183 D WifiService: getConnectionInfo uid=1000
09-01 21:09:28.126 2552 2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.126 2552 2552 D StatusBar.NetworkController: slot=-10;action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.126 2552 2552 D StatusBar.NetworkController: updateNetworkName slotId=1 chosenNetType=13 mNetworkName=中国移动 mNetworkTypeName=4G
09-01 21:09:28.127 1561 4100 D WifiService: getWifiEnabledState uid=1000
09-01 21:09:28.127 2650 2767 I QCNEJ/CndHalConnector: -> SND notifyRatConnectionStatusChanged(rat = 1, CONNECTING)
09-01 21:09:28.127 4722 4722 D TrafficManageService: wifi2mobile:android.net.wifi.STATE_CHANGE
09-01 21:09:28.128 1561 4183 D WifiService: getWifiEnabledState uid=1000
09-01 21:09:28.134 1561 2457 D WifiStateMachine: L2ConnectedState clearTargetBssid any key="jiatai 5G"-WPA_PSK
09-01 21:09:28.135 1561 2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setBssid succeeded
09-01 21:09:28.135 1561 2457 D WifiCountryCode: Set ready: false
09-01 21:09:28.135 1561 2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK roam=false static=false
09-01 21:09:28.135 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false
09-01 21:09:28.136 1561 2457 D WifiStateMachine: ObtainingIpAddress clearTargetBssid any key="jiatai 5G"-WPA_PSK
case WifiMonitor.NETWORK_CONNECTION_EVENT:
if (mVerboseLoggingEnabled) log("Network connection established");
mLastNetworkId = lookupFrameworkNetworkId(message.arg1);
mWifiConfigManager.clearRecentFailureReason(mLastNetworkId);
mLastBssid = (String) message.obj;
reasonCode = message.arg2;
// TODO: This check should not be needed after WifiStateMachinePrime refactor.
// Currently, the last connected network configuration is left in
// wpa_supplicant, this may result in wpa_supplicant initiating connection
// to it after a config store reload. Hence the old network Id lookups may not
// work, so disconnect the network and let network selector reselect a new
// network.
config = getCurrentWifiConfiguration();
if (config != null) {
mWifiInfo.setBSSID(mLastBssid);
mWifiInfo.setNetworkId(mLastNetworkId);
ScanDetailCache scanDetailCache =
mWifiConfigManager.getScanDetailCacheForNetwork(config.networkId);
if (scanDetailCache != null && mLastBssid != null) {
ScanResult scanResult = scanDetailCache.getScanResult(mLastBssid);
if (scanResult != null) {
mWifiInfo.setFrequency(scanResult.frequency);
}
}
mWifiConnectivityManager.trackBssid(mLastBssid, true, reasonCode);
// We need to get the updated pseudonym from supplicant for EAP-SIM/AKA/AKA'
if (config.enterpriseConfig != null
&& TelephonyUtil.isSimEapMethod(
config.enterpriseConfig.getEapMethod())) {
String anonymousIdentity = mWifiNative.getEapAnonymousIdentity();
if (anonymousIdentity != null) {
config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
} else {
Log.d(TAG, "Failed to get updated anonymous identity"
+ " from supplicant, reset it in WifiConfiguration.");
config.enterpriseConfig.setAnonymousIdentity(null);
}
mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
}
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);
} else {
logw("Connected to unknown networkId " + mLastNetworkId
+ ", disconnecting...");
sendMessage(CMD_DISCONNECT);
}
break;
收到该消息后进入到ObtainingIpState状态,与 (九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程 梳理的流程对接。
这两个消息都是SupplicantStaIfaceHal的SupplicantStaIfaceHalCallback上报上来的。
private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
private static final int WLAN_REASON_IE_IN_4WAY_DIFFERS = 17; // IEEE 802.11i
private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
@Override
public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
ArrayList<Byte> ssid) {
synchronized (mLock) {
logCallback("onStateChanged");
SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
WifiSsid wifiSsid =
WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
if (newSupplicantState == SupplicantState.COMPLETED) {
mWifiMonitor.broadcastNetworkConnectionEvent(
mIfaceName, getCurrentNetworkId(), bssidStr);
}
mWifiMonitor.broadcastSupplicantStateChangeEvent(
mIfaceName, getCurrentNetworkId(), wifiSsid, bssidStr, newSupplicantState);
}
}