这是android 11高通车机系统的wifi热点日志流程
Line 87696: 05-30 17:04:43.457 10499 10499 V WifiManager: registerSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@3c702c3, executor=android.os.HandlerExecutor@465c740
Line 92004: 05-30 17:04:46.216 10499 10499 V WifiManager: unregisterSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@3c702c3
Line 93443: 05-30 17:04:47.399 1803 1881 E WifiManager: wqy- startTetheredHotspot
Line 93444: 05-30 17:04:47.400 809 3327 E WifiService: wqy-startTetheredHotspot
Line 93446: 05-30 17:04:47.401 809 3327 E WifiService: wqy-startSoftApInternal
Line 93447: 05-30 17:04:47.401 809 3327 E WifiActiveModeWarden: wqy-startSoftAp, 237line
Line 93447: 05-30 17:04:47.401 809 3327 E WifiActiveModeWarden: wqy-startSoftAp, 237line
Line 93448: 05-30 17:04:47.401 809 1062 E WifiController: wqy-processMessageFiltered, CMD_SET_AP, 855line
Line 93449: 05-30 17:04:47.401 809 1062 E WifiController: wqy-processMessageFiltered, CMD_SET_AP, msg.arg1 == 1 , 855line
Line 93450: 05-30 17:04:47.402 809 1062 E WifiActiveModeWarden: wqy-startSoftApModeManager
Line 93450: 05-30 17:04:47.402 809 1062 E WifiActiveModeWarden: wqy-startSoftApModeManager
Line 93451: 05-30 17:04:47.402 809 1062 D WifiActiveModeWarden: Starting SoftApModeManager config = null
Line 93455: 05-30 17:04:47.409 809 1062 D SoftApManager: wqy-SoftApManager: new SoftApManager
Line 93455: 05-30 17:04:47.409 809 1062 D SoftApManager: wqy-SoftApManager: new SoftApManager
Line 93455: 05-30 17:04:47.409 809 1062 D SoftApManager: wqy-SoftApManager: new SoftApManager
Line 93455: 05-30 17:04:47.409 809 1062 D SoftApManager: wqy-SoftApManager: new SoftApManager
Line 93456: 05-30 17:04:47.410 809 1062 D SoftApManager: wqy-SoftApManager: softApConfig is null
Line 93456: 05-30 17:04:47.410 809 1062 D SoftApManager: wqy-SoftApManager: softApConfig is null
Line 93456: 05-30 17:04:47.410 809 1062 D SoftApManager: wqy-SoftApManager: softApConfig is null
Line 93457: 05-30 17:04:47.410 809 1062 D SoftApManager: wqy-SoftApManager: softApConfig is not null
Line 93457: 05-30 17:04:47.410 809 1062 D SoftApManager: wqy-SoftApManager: softApConfig is not null
Line 93457: 05-30 17:04:47.410 809 1062 D SoftApManager: wqy-SoftApManager: softApConfig is not null
Line 93458: 05-30 17:04:47.410 809 1062 E WifiApConfigStore: wqy-randomizeBssidIfUnset
Line 93459: 05-30 17:04:47.410 809 1062 E WifiApConfigStore: wqy-randomizeBssidIfUnset, bssid is null, set randoem bssid
Line 93486: 05-30 17:04:47.482 809 1062 E WifiApConfigStore: wqy-randomizeBssidIfUnset, bssid is not null
Line 94639: 05-30 17:04:48.683 809 1062 D SoftApManager: band 1 iface wlan1 country US
Line 94757: 05-30 17:04:48.871 809 1062 D SoftApManager: Soft AP is started
Line 94758: 05-30 17:04:48.873 809 1062 D SoftApManager: SoftAp is ready for use
Line 94768: 05-30 17:04:48.878 809 1062 D SoftApManager: Resetting connected clients on start
Line 94774: 05-30 17:04:48.880 809 1062 D SoftApManager: Timeout message scheduled, delay = 600000
Line 96312: 05-30 17:04:50.182 809 1062 D SoftApManager: Channel switched. Frequency: 2412 Bandwidth: 2
Line 96377: 05-30 17:04:50.296 809 1062 D SoftApManager: start to init softAP vendor
Line 96378: 05-30 17:04:50.296 809 1062 I SoftApManager: wlan.sample.vendor_init not set to 1, not set sample values
Line 118101: 05-30 17:05:08.309 10499 10499 V WifiManager: registerSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@3c702c3, executor=android.os.HandlerExecutor@625c777
Line 122649: 05-30 17:05:11.323 10499 10499 V WifiManager: unregisterSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@3c702c3
Line 124433: 05-30 17:05:13.102 809 1721 E WifiService: wqy-setWifiEnabled2
Line 124435: 05-30 17:05:13.104 809 1062 D WifiActiveModeWarden: Starting ClientModeManager
Line 125164: 05-30 17:05:13.497 809 832 E WifiService: wqy-startScan
Line 128320: 05-30 17:05:16.200 10499 10499 V WifiManager: registerSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@fd2bd8c, executor=android.os.HandlerExecutor@8c38cd5
Line 131584: 05-30 17:05:19.063 10499 10499 V WifiManager: unregisterSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@fd2bd8c
Line 137173: 05-30 17:05:25.267 809 1062 D SoftApManager: CMD_ASSOCIATED_STATIONS_CHANGED, Client: 02:7d:6f:f1:50:18 isConnected: true
Line 137176: 05-30 17:05:25.267 809 1062 D SoftApManager: The connected wifi stations have changed with count: 1: [WifiClient{mMacAddress=02:7d:6f:f1:50:18}]
Line 137180: 05-30 17:05:25.269 809 1062 D SoftApManager: Timeout message canceled
Line 206289: 05-30 17:06:29.222 10499 10499 V WifiManager: registerSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@fd2bd8c, executor=android.os.HandlerExecutor@5dff756
Line 209320: 05-30 17:06:31.406 809 3327 E WifiService: wqy-startScan
Line 209968: 05-30 17:06:31.985 10499 10499 V WifiManager: unregisterSoftApCallback: callback=com.android.settings.wifi.tether.WifiTetherSoftApManager$1@fd2bd8c
1、一切调用都从framework的WifiManager开始, 根据注释,这儿的softapconfig有可能是指定的softap,也有可能使用persisted softap
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
/**
* Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
* Note that starting Soft AP mode may disable station mode operation if the device does not
* support concurrency.
* @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP,
* or null to use the persisted Soft AP configuration that was previously
* set using {@link #setSoftApConfiguration(softApConfiguration)}.
* @return {@code true} if the operation succeeded, {@code false} otherwise
*
* @hide
*/
@SystemApi
@RequiresPermission(anyOf = {
android.Manifest.permission.NETWORK_STACK,
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
Log.e(TAG, "wqy- startTetheredHotspot");
try {
return mService.startTetheredHotspot(softApConfig);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2、然后会调用到WifiService,实际调用都在WifiServiceImpl,会调用到startSoftApInternal
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
/**
* see {@link android.net.wifi.WifiManager#startTetheredHotspot(SoftApConfiguration)}
* @param softApConfig SSID, security and channel details as part of SoftApConfiguration
* @return {@code true} if softap start was triggered
* @throws SecurityException if the caller does not have permission to start softap
*/
@Override
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
Log.e(TAG, "wqy-startTetheredHotspot");
if (!startSoftApInternal(new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
mTetheredSoftApTracker.getSoftApCapability()))) {
mTetheredSoftApTracker.setFailedWhileEnabling();
return false;
}
return true;
}
/**
* Internal method to start softap mode. Callers of this method should have already checked
* proper permissions beyond the NetworkStack permission.
*/
private boolean startSoftApInternal(SoftApModeConfiguration apConfig) {
int uid = Binder.getCallingUid();
boolean privileged = isSettingsOrSuw(Binder.getCallingPid(), uid);
mLog.trace("startSoftApInternal uid=% mode=%")
.c(uid).c(apConfig.getTargetMode()).flush();
// null wifiConfig is a meaningful input for CMD_SET_AP; it means to use the persistent
// AP config.
SoftApConfiguration softApConfig = apConfig.getSoftApConfiguration();
if (softApConfig != null
&& (!WifiApConfigStore.validateApWifiConfiguration(softApConfig, privileged)
|| !validateSoftApBand(softApConfig.getBand()))) {
Log.e(TAG, "Invalid SoftApConfiguration");
return false;
}
mActiveModeWarden.startSoftAp(apConfig);
return true;
}
这里有个WifiControll统一处理softap的状态,会在ActiveModeWarden.java里有个内部类的WifiControl, 这儿是设置wifisoftap配置信息的
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
/** Starts SoftAp. */
public void startSoftAp(SoftApModeConfiguration softApConfig) {
mWifiController.sendMessage(WifiController.CMD_SET_AP, 1, 0, softApConfig);
}
case CMD_SET_AP:
// note: CMD_SET_AP is handled/dropped in ECM mode - will not start here
if (msg.arg1 == 1) {
startSoftApModeManager((SoftApModeConfiguration) msg.obj);
} else {
stopSoftApModeManagers(msg.arg2);
}
break;
这里会创建一个softapmanager, 用于softap热点相关的操作
ActiveModeManager manager =
mWifiInjector.makeSoftApManager(listener, callback, softApConfig);
/**
* Method to enable soft ap for wifi hotspot.
*
* The supplied SoftApModeConfiguration includes the target softap WifiConfiguration (or null if
* the persisted config is to be used) and the target operating mode (ex,
* {@link WifiManager#IFACE_IP_MODE_TETHERED} {@link WifiManager#IFACE_IP_MODE_LOCAL_ONLY}).
*
* @param softApConfig SoftApModeConfiguration for the hostapd softap
*/
private void startSoftApModeManager(@NonNull SoftApModeConfiguration softApConfig) {
Log.d(TAG, "Starting SoftApModeManager config = "
+ softApConfig.getSoftApConfiguration());
Preconditions.checkState(softApConfig.getTargetMode() == IFACE_IP_MODE_LOCAL_ONLY
|| softApConfig.getTargetMode() == IFACE_IP_MODE_TETHERED);
WifiManager.SoftApCallback callback =
softApConfig.getTargetMode() == IFACE_IP_MODE_LOCAL_ONLY
? mLohsCallback : mSoftApCallback;
SoftApListener listener = new SoftApListener();
ActiveModeManager manager =
mWifiInjector.makeSoftApManager(listener, callback, softApConfig);
listener.setActiveModeManager(manager);
manager.start();
manager.setRole(getRoleForSoftApIpMode(softApConfig.getTargetMode()));
mActiveModeManagers.add(manager);
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiInjector.java
/**
* Create a SoftApManager.
* @param config SoftApModeConfiguration object holding the config and mode
* @return an instance of SoftApManager
*/
public SoftApManager makeSoftApManager(@NonNull ActiveModeManager.Listener listener,
@NonNull WifiManager.SoftApCallback callback,
@NonNull SoftApModeConfiguration config) {
return new SoftApManager(mContext, mWifiHandlerThread.getLooper(),
mFrameworkFacade, mWifiNative, mCountryCode.getCountryCode(), listener, callback,
mWifiApConfigStore, config, mWifiMetrics, mSarManager, mWifiDiagnostics);
}
这里当softapconfig不为null,并且bssid为null的时候,会自己创建一个随机的mac
frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java
SoftApManager() {
if (softApConfig != null) {
mIsRandomizeBssid = softApConfig.getBssid() == null;
softApConfig = mWifiApConfigStore.randomizeBssidIfUnset(mContext, softApConfig);
}
}
这里会根据WIFI_UID获取签名证书相关的数据,并进行HMacSHA256的加密,也不能说加密,
然后用ssid值进行进行hash运算,经过一系列掩码运算,获取字节序里的6位16进制数作为mac地
址。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiApConfigStore.java
SoftApConfiguration randomizeBssidIfUnset(Context context, SoftApConfiguration config) {
Log.e(TAG, " wqy--randomizeBssidIfUnset");
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
if (config.getBssid() == null && context.getResources().getBoolean(
R.bool.config_wifi_ap_mac_randomization_supported)) {
Log.e(TAG, " wqy-randomizeBssidIfUnset, bssid is null, set randoem bssid");
MacAddress macAddress = mMacAddressUtil.calculatePersistentMac(config.getSsid(),
mMacAddressUtil.obtainMacRandHashFunctionForSap(Process.WIFI_UID));
if (macAddress == null) {
Log.e(TAG, "Failed to calculate MAC from SSID. "
+ "Generating new random MAC instead.");
macAddress = MacAddressUtils.createRandomUnicastAddress();
}
configBuilder.setBssid(macAddress);
}
Log.e(TAG, " wqy-randomizeBssidIfUnset, bssid is not null");
return configBuilder.build();
}
/**
* Computes the persistent randomized MAC using the given key and hash function.
* @param key the key to compute MAC address for
* @param hashFunction the hash function that will perform the MAC address computation.
* @return The persistent randomized MAC address or null if inputs are invalid.
*/
public MacAddress calculatePersistentMac(String key, Mac hashFunction) {
if (key == null || hashFunction == null) {
return null;
}
Log.e(TAG, "wqy-calculatePersistentMac, key is " + key);
byte[] hashedBytes;
try {
hashedBytes = hashFunction.doFinal(key.getBytes(StandardCharsets.UTF_8));
Log.e(TAG, "wqy-calculatePersistentMac, hashedBytes is " + hashedBytes.toString());
} catch (ProviderException | IllegalStateException e) {
Log.e(TAG, "Failure in calculatePersistentMac", e);
return null;
}
ByteBuffer bf = ByteBuffer.wrap(hashedBytes);
Log.e(TAG, "wqy-calculatePersistentMac, bf = " + bf.toString());
long longFromSsid = bf.getLong();
/**
* Masks the generated long so that it represents a valid randomized MAC address.
* Specifically, this sets the locally assigned bit to 1, multicast bit to 0
*/
longFromSsid &= MAC_ADDRESS_VALID_LONG_MASK;
longFromSsid |= MAC_ADDRESS_LOCALLY_ASSIGNED_MASK;
longFromSsid &= ~MAC_ADDRESS_MULTICAST_MASK;
bf.clear();
bf.putLong(0, longFromSsid);
Log.e(TAG, "wqy-calculatePersistentMac, longFromSsid " + Long.toHexString(longFromSsid));
// MacAddress.fromBytes requires input of length 6, which is obtained from the
// last 6 bytes from the generated long.
MacAddress macAddress = MacAddress.fromBytes(Arrays.copyOfRange(bf.array(), 2, 8));
return macAddress;
}
private Mac obtainMacRandHashFunctionInternal(int uid, String alias) {
try {
KeyStore keyStore = AndroidKeyStoreProvider.getKeyStoreForUid(uid);
// tries to retrieve the secret, and generate a new one if it's unavailable.
Key key = keyStore.getKey(alias, null);
if (key == null) {
key = generateAndPersistNewMacRandomizationSecret(uid, alias);
}
if (key == null) {
Log.e(TAG, "Failed to generate secret for " + alias);
return null;
}
Mac result = Mac.getInstance("HmacSHA256");
result.init(key);
return result;
} catch (KeyStoreException | NoSuchAlgorithmException | InvalidKeyException
| UnrecoverableKeyException | NoSuchProviderException e) {
Log.e(TAG, "Failure in obtainMacRandHashFunction", e);
return null;
}
}
接下来该往下调用startsoftap了,通过SoftApManager往下调用,会调用到WifiNative,这儿就开始往hal层调用了
rameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java
private int startSoftAp() {
Log.e(TAG, "wqy-startSoftAp");
SoftApConfiguration config = mApConfig.getSoftApConfiguration();
if (config == null || config.getSsid() == null) {
Log.e(TAG, "Unable to start soft AP without valid configuration");
return ERROR_GENERIC;
}
Log.d(TAG, "band " + config.getBand() + " iface "
+ mApInterfaceName + " country " + mCountryCode);
if (!mWifiNative.startSoftAp(mApInterfaceName,
localConfigBuilder.build(), mSoftApListener)) {
Log.e(TAG, "Soft AP start failed");
return ERROR_GENERIC;
}
Log.d(TAG, "Soft AP is started ");
return SUCCESS;
}
接下来就是WifiCondManager注册回调,hostapdHal调用底层接口
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
/**
* Start Soft AP operation using the provided configuration.
*
* @param ifaceName Name of the interface.
* @param config Configuration to use for the soft ap created.
* @param listener Callback for AP events.
* @return true on success, false otherwise.
*/
public boolean startSoftAp(
@NonNull String ifaceName, SoftApConfiguration config, SoftApListener listener) {
Log.e(TAG, "wqy-startSoftAp");
if (!mWifiCondManager.registerApCallback(ifaceName, Runnable::run, listener)) {
Log.e(TAG, "Failed to register ap listener");
return false;
}
Log.e(TAG, "wqy-startSoftAp, mWifiCondManager.registerApCallback is ok");
if (!mHostapdHal.addAccessPoint(ifaceName, config, listener::onFailure)) {
Log.e(TAG, "Failed to add acccess point");
mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
return false;
}
Log.e(TAG, "wqy-startSoftAp, mHostapdHal.addAccessPoint is ok");
return true;
}