直接计算在 wifi_chip.cpp 中
std::string getWlanIfaceName(unsigned idx) {
if (idx >= kMaxWlanIfaces) {
CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
return {};
}
std::array<char, PROPERTY_VALUE_MAX> buffer;
if (idx == 0 || idx == 1) {
const char* altPropName =
(idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
auto res = property_get(altPropName, buffer.data(), nullptr);
if (res > 0) return buffer.data();
}
std::string propName = "wifi.interface." + std::to_string(idx);
auto res = property_get(propName.c_str(), buffer.data(), nullptr);
if (res > 0) return buffer.data();
return "wlan" + std::to_string(idx);
}
返回了 wlanN 字串,其调用发生在 allocateApOrStaIfaceName 接口
/* wifi_chip.cpp */
// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
// not already in use.
// Note: This doesn't check the actual presence of these interfaces.
std::string WifiChip::allocateApOrStaIfaceName(uint32_t start_idx) {
for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
const auto ifname = getWlanIfaceName(idx);
if (findUsingName(ap_ifaces_, ifname)) continue;
if (findUsingName(sta_ifaces_, ifname)) continue;
return ifname;
}
// This should never happen. We screwed up somewhere if it did.
CHECK(false) << "All wlan interfaces in use already!";
return {};
}
继续回溯:allocateStaIfaceName
/* wifi_chip.cpp */
// STA iface names start with idx 0.
// Primary STA iface will always be 0.
std::string WifiChip::allocateStaIfaceName() {
return allocateApOrStaIfaceName(0);
}
createStaIface -> createStaIfaceInternal
/* wifi_chip.cpp */
Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::createStaIfaceInternal, hidl_status_cb);
}
std::pair<WifiStatus, sp<V1_3::IWifiStaIface>>
WifiChip::createStaIfaceInternal() {
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
std::string ifname = allocateStaIfaceName();
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->createVirtualInterface(
ifname,
hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to add interface: " << ifname << " "
<< legacyErrorToString(legacy_status);
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
sta_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
}
}
setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
}
上面的调用都发生在 HIDL 的 server 端,代码在 hardware/interfaces/wifi/1.0/IWifiChip.hal 中定义,而在 client 端的调用发生在 HalDeviceManager.java 中 executeChipReconfiguration 接口:
/* HalDeviceManager.java */
/**
* Performs chip reconfiguration per the input:
* - Removes the specified interfaces
* - Reconfigures the chip to the new chip mode (if necessary)
* - Creates the new interface
*
* Returns the newly created interface or a null on any error.
*/
private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData,
int ifaceType) {
if (mDbg) {
Log.d(TAG, "executeChipReconfiguration: ifaceCreationData=" + ifaceCreationData
+ ", ifaceType=" + ifaceType);
}
synchronized (mLock) {
try {
// is this a mode change?
boolean isModeConfigNeeded = !ifaceCreationData.chipInfo.currentModeIdValid
|| ifaceCreationData.chipInfo.currentModeId != ifaceCreationData.chipModeId;
if (mDbg) Log.d(TAG, "isModeConfigNeeded=" + isModeConfigNeeded);
// first delete interfaces/change modes
if (isModeConfigNeeded) {
// remove all interfaces pre mode-change
// TODO: is this necessary? note that even if we don't want to explicitly
// remove the interfaces we do need to call the onDeleted callbacks - which
// this does
for (WifiIfaceInfo[] ifaceInfos: ifaceCreationData.chipInfo.ifaces) {
for (WifiIfaceInfo ifaceInfo: ifaceInfos) {
removeIfaceInternal(ifaceInfo.iface); // ignore return value
}
}
WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
ifaceCreationData.chipModeId);
updateRttControllerOnModeChange();
if (status.code != WifiStatusCode.SUCCESS) {
Log.e(TAG, "executeChipReconfiguration: configureChip error: "
+ statusString(status));
return null;
}
} else {
// remove all interfaces on the delete list
for (WifiIfaceInfo ifaceInfo: ifaceCreationData.interfacesToBeRemovedFirst) {
removeIfaceInternal(ifaceInfo.iface); // ignore return value
}
}
// create new interface
Mutable<WifiStatus> statusResp = new Mutable<>();
Mutable<IWifiIface> ifaceResp = new Mutable<>();
switch (ifaceType) {
case IfaceType.STA:
ifaceCreationData.chipInfo.chip.createStaIface(
(WifiStatus status, IWifiStaIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
case IfaceType.AP:
ifaceCreationData.chipInfo.chip.createApIface(
(WifiStatus status, IWifiApIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
case IfaceType.P2P:
ifaceCreationData.chipInfo.chip.createP2pIface(
(WifiStatus status, IWifiP2pIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
case IfaceType.NAN:
ifaceCreationData.chipInfo.chip.createNanIface(
(WifiStatus status, IWifiNanIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
}
if (statusResp.value.code != WifiStatusCode.SUCCESS) {
Log.e(TAG, "executeChipReconfiguration: failed to create interface ifaceType="
+ ifaceType + ": " + statusString(statusResp.value));
return null;
}
return ifaceResp.value;
} catch (RemoteException e) {
Log.e(TAG, "executeChipReconfiguration exception: " + e);
return null;
}
}
}
被同为 HalDeviceManager 类中的 createIfaceIfPossible 方法调用,而它则被 createIface 调用:
/* HalDeviceManager.java */
private IWifiIface createIface(int ifaceType, InterfaceDestroyedListener destroyedListener,
Handler handler) {
if (mDbg) {
Log.d(TAG, "createIface: ifaceType=" + ifaceType);
}
synchronized (mLock) {
WifiChipInfo[] chipInfos = getAllChipInfo();
if (chipInfos == null) {
Log.e(TAG, "createIface: no chip info found");
stopWifi(); // major error: shutting down
return null;
}
if (!validateInterfaceCache(chipInfos)) {
Log.e(TAG, "createIface: local cache is invalid!");
stopWifi(); // major error: shutting down
return null;
}
IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, destroyedListener,
handler);
if (iface != null) { // means that some configuration has changed
if (!dispatchAvailableForRequestListeners()) {
return null; // catastrophic failure - shut down
}
}
return iface;
}
}
private IWifiIface createIfaceIfPossible(WifiChipInfo[] chipInfos, int ifaceType,
InterfaceDestroyedListener destroyedListener, Handler handler) {
if (VDBG) {
Log.d(TAG, "createIfaceIfPossible: chipInfos=" + Arrays.deepToString(chipInfos)
+ ", ifaceType=" + ifaceType);
}
synchronized (mLock) {
IfaceCreationData bestIfaceCreationProposal = null;
for (WifiChipInfo chipInfo: chipInfos) {
for (IWifiChip.ChipMode chipMode: chipInfo.availableModes) {
for (IWifiChip.ChipIfaceCombination chipIfaceCombo : chipMode
.availableCombinations) {
int[][] expandedIfaceCombos = expandIfaceCombos(chipIfaceCombo);
if (VDBG) {
Log.d(TAG, chipIfaceCombo + " expands to "
+ Arrays.deepToString(expandedIfaceCombos));
}
for (int[] expandedIfaceCombo: expandedIfaceCombos) {
IfaceCreationData currentProposal = canIfaceComboSupportRequest(
chipInfo, chipMode, expandedIfaceCombo, ifaceType);
if (compareIfaceCreationData(currentProposal,
bestIfaceCreationProposal)) {
if (VDBG) Log.d(TAG, "new proposal accepted");
bestIfaceCreationProposal = currentProposal;
}
}
}
}
}
if (bestIfaceCreationProposal != null) {
IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal, ifaceType);
if (iface != null) {
InterfaceCacheEntry cacheEntry = new InterfaceCacheEntry();
cacheEntry.chip = bestIfaceCreationProposal.chipInfo.chip;
cacheEntry.chipId = bestIfaceCreationProposal.chipInfo.chipId;
cacheEntry.name = getName(iface);
cacheEntry.type = ifaceType;
if (destroyedListener != null) {
cacheEntry.destroyedListeners.add(
new InterfaceDestroyedListenerProxy(
cacheEntry.name, destroyedListener, handler));
}
cacheEntry.creationTime = mClock.getUptimeSinceBootMillis();
if (mDbg) Log.d(TAG, "createIfaceIfPossible: added cacheEntry=" + cacheEntry);
mInterfaceInfoCache.put(
Pair.create(cacheEntry.name, cacheEntry.type), cacheEntry);
return iface;
}
}
}
return null;
}
实际调用者为 createStaIface:
/**
* Create a STA interface if possible. Changes chip mode and removes conflicting interfaces if
* needed and permitted by priority.
*
* @param destroyedListener Optional (nullable) listener to call when the allocated interface
* is removed. Will only be registered and used if an interface is
* created successfully.
* @param handler Handler on which to dispatch listener. Null implies the listener will be
* invoked synchronously from the context of the client which triggered the
* iface destruction.
* @return A newly created interface - or null if the interface could not be created.
*/
public IWifiStaIface createStaIface(
@Nullable InterfaceDestroyedListener destroyedListener, @Nullable Handler handler) {
return (IWifiStaIface) createIface(IfaceType.STA, destroyedListener, handler);
}
而回溯到 WifiVendorHal.java 中的同名函数 createStaIface:
/* WifiVendorHal.java */
/**
* Create a STA iface using {@link HalDeviceManager}.
*
* @param destroyedListener Listener to be invoked when the interface is destroyed.
* @return iface name on success, null otherwise.
*/
public String createStaIface(InterfaceDestroyedListener destroyedListener) {
synchronized (sLock) {
IWifiStaIface iface = mHalDeviceManager.createStaIface(
new StaInterfaceDestroyedListenerInternal(destroyedListener), null);
if (iface == null) {
mLog.err("Failed to create STA iface").flush();
return stringResult(null);
}
String ifaceName = mHalDeviceManager.getName((IWifiIface) iface);
if (TextUtils.isEmpty(ifaceName)) {
mLog.err("Failed to get iface name").flush();
return stringResult(null);
}
if (!registerStaIfaceCallback(iface)) {
mLog.err("Failed to register STA iface callback").flush();
return stringResult(null);
}
if (!retrieveWifiChip((IWifiIface) iface)) {
mLog.err("Failed to get wifi chip").flush();
return stringResult(null);
}
enableLinkLayerStats(iface);
mIWifiStaIfaces.put(ifaceName, iface);
return ifaceName;
}
}
继而进入 WifiNative.java 中的同名函数 createStaIface(也可能被其内部 startVendorHalSta 调用):
/* WifiNative.java */
/**
* Helper function to handle creation of STA iface.
* For devices which do not the support the HAL, this will bypass HalDeviceManager &
* teardown any existing iface.
*/
private String createStaIface(@NonNull Iface iface) {
synchronized (mLock) {
if (mWifiVendorHal.isVendorHalSupported()) {
return mWifiVendorHal.createStaIface(
new InterfaceDestoyedListenerInternal(iface.id));
} else {
Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
return handleIfaceCreationWhenVendorHalNotSupported(iface);
}
}
}
进而回归到配置过程的处理函数:
- setupInterfaceForClientInConnectivityMode
- setupInterfaceForClientInScanMode