(九十二) Android O WiFi热点 开启流程梳理续
发布日期:2021-06-30 15:25:18 浏览次数:2 分类:技术文章

本文共 32571 字,大约阅读时间需要 108 分钟。

前言:之前在 梳理到了WifiStateMachine就没梳理得下去了,现在继续梳理下面流程。

 

1.流程梳理

class SoftApState extends State {        private SoftApManager mSoftApManager;        private String mIfaceName;        private int mMode;        private class SoftApListener implements SoftApManager.Listener {            @Override            public void onStateChanged(int state, int reason) {                if (state == WIFI_AP_STATE_DISABLED) {                    sendMessage(CMD_AP_STOPPED);                } else if (state == WIFI_AP_STATE_FAILED) {                    sendMessage(CMD_START_AP_FAILURE);                }                setWifiApState(state, reason, mIfaceName, mMode);            }        }        @Override        public void enter() {            final Message message = getCurrentMessage();            if (message.what != CMD_START_AP) {                throw new RuntimeException("Illegal transition to SoftApState: " + message);            }            SoftApModeConfiguration config = (SoftApModeConfiguration) message.obj;            mMode = config.getTargetMode();            IApInterface apInterface = null;            Pair
statusAndInterface = mWifiNative.setupForSoftApMode(); if (statusAndInterface.first == WifiNative.SETUP_SUCCESS) { apInterface = statusAndInterface.second; } else { incrementMetricsForSetupFailure(statusAndInterface.first); } if (apInterface == null) { setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL, null, mMode); /** * Transition to InitialState to reset the * driver/HAL back to the initial state. */ transitionTo(mInitialState); return; } try { mIfaceName = apInterface.getInterfaceName(); } catch (RemoteException e) { // Failed to get the interface name. The name will not be available for // the enabled broadcast, but since we had an error getting the name, we most likely // won't be able to fully start softap mode. } checkAndSetConnectivityInstance(); mSoftApManager = mWifiInjector.makeSoftApManager(mNwService, new SoftApListener(), apInterface, config.getWifiConfiguration()); mSoftApManager.start(); mWifiStateTracker.updateState(WifiStateTracker.SOFT_AP); }

先看下mWifiNative.setupForSoftApMode,与WiFi启动的时候做个对照

/**    * Setup wifi native for Client mode operations.    *    * 1. Starts the Wifi HAL and configures it in client/STA mode.    * 2. Setup Wificond to operate in client mode and retrieve the handle to use for client    * operations.    *    * @return Pair of 
to indicate the status and the associated wificond * client interface binder handler (will be null on failure). */ public Pair
setupForClientMode() { if (!startHalIfNecessary(true)) { Log.e(mTAG, "Failed to start HAL for client mode"); return Pair.create(SETUP_FAILURE_HAL, null); } IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode(); if (iClientInterface == null) { return Pair.create(SETUP_FAILURE_WIFICOND, null); } return Pair.create(SETUP_SUCCESS, iClientInterface); } /** * Setup wifi native for AP mode operations. * * 1. Starts the Wifi HAL and configures it in AP mode. * 2. Setup Wificond to operate in AP mode and retrieve the handle to use for ap operations. * * @return Pair of
to indicate the status and the associated wificond * AP interface binder handler (will be null on failure). */ public Pair
setupForSoftApMode() { if (!startHalIfNecessary(false)) { Log.e(mTAG, "Failed to start HAL for AP mode"); return Pair.create(SETUP_FAILURE_HAL, null); } IApInterface iApInterface = mWificondControl.setupDriverForSoftApMode(); if (iApInterface == null) { return Pair.create(SETUP_FAILURE_WIFICOND, null); } return Pair.create(SETUP_SUCCESS, iApInterface); }

区别

1.startHalIfNecessary传入的参数不同

2.调用的是mWificondControl.setupDriverForClientMode/mWificondControl.setupDriverForSoftApMode

1.1 startHalIfNecessary

WifiNative

/**     * Bring up the Vendor HAL and configure for STA mode or AP mode, if vendor HAL is supported.     *     * @param isStaMode true to start HAL in STA mode, false to start in AP mode.     * @return false if the HAL start fails, true if successful or if vendor HAL not supported.     */    private boolean startHalIfNecessary(boolean isStaMode) {        if (!mWifiVendorHal.isVendorHalSupported()) {            Log.i(mTAG, "Vendor HAL not supported, Ignore start...");            return true;        }        return mWifiVendorHal.startVendorHal(isStaMode);    }

WifiVendorHal

/**     * Bring up the HIDL Vendor HAL and configure for STA mode or AP mode.     *     * @param isStaMode true to start HAL in STA mode, false to start in AP mode.     */    public boolean startVendorHal(boolean isStaMode) {        synchronized (sLock) {            if (mIWifiStaIface != null) return boolResult(false);            if (mIWifiApIface != null) return boolResult(false);            if (!mHalDeviceManager.start()) {                return startFailedTo("start the vendor HAL");            }            IWifiIface iface;            if (isStaMode) {                mIWifiStaIface = mHalDeviceManager.createStaIface(null, null);                if (mIWifiStaIface == null) {                    return startFailedTo("create STA Iface");                }                iface = (IWifiIface) mIWifiStaIface;                if (!registerStaIfaceCallback()) {                    return startFailedTo("register sta iface callback");                }                mIWifiRttController = mHalDeviceManager.createRttController(iface);                if (mIWifiRttController == null) {                    return startFailedTo("create RTT controller");                }                if (!registerRttEventCallback()) {                    return startFailedTo("register RTT iface callback");                }                enableLinkLayerStats();            } else {                mIWifiApIface = mHalDeviceManager.createApIface(null, null);                if (mIWifiApIface == null) {                    return startFailedTo("create AP Iface");                }                iface = (IWifiIface) mIWifiApIface;            }            mIWifiChip = mHalDeviceManager.getChip(iface);            if (mIWifiChip == null) {                return startFailedTo("get the chip created for the Iface");            }            if (!registerChipCallback()) {                return startFailedTo("register chip callback");            }            mLog.i("Vendor Hal started successfully");            return true;        }    }

mHalDeviceManager.start()这个流程是和WiFi启动一样的,就是将frameworks/opt/net/wifi/libwifi_hal/Android.mk中的libwifi-hal-fallback/libwifi-hal-bcm/libwifi-hal-qcom/libwifi-hal-mt66xx 初始化一下,过程略。

区别在于mHalDeviceManager.createApIface是创建ap的interface。

先看一下WiFi启动的时序图

可以料想softap这块也是加载驱动。

HalDeviceManager

/**     * Create AP interface if possible (see createStaIface doc).     */    public IWifiApIface createApIface(InterfaceDestroyedListener destroyedListener,            Looper looper) {        return (IWifiApIface) createIface(IfaceType.AP, destroyedListener, looper);    }    private IWifiIface createIface(int ifaceType, InterfaceDestroyedListener destroyedListener,            Looper looper) {        if (DBG) 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,                    looper);            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, Looper looper) {        if (DBG) {            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 (DBG) {                            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 (DBG) 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(destroyedListener,                                        looper == null ? Looper.myLooper() : looper));                    }                    if (DBG) Log.d(TAG, "createIfaceIfPossible: added cacheEntry=" + cacheEntry);                    mInterfaceInfoCache.put(cacheEntry.name, cacheEntry);                    return iface;                }            }        }        return null;    }    /**     * 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 (DBG) {            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 (DBG) 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);                    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
statusResp = new Mutable<>(); Mutable
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; } } }

                    WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(

                            ifaceCreationData.chipModeId);

这下面应该也和WiFi启动的流程一样,是加载驱动。区别应该是下面的switch-case

 

hardware/interfaces/wifi/1.1/default/wifi_chip.cpp

createApIface

Return
WifiChip::createApIface(createApIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::createApIfaceInternal, hidl_status_cb);}std::pair
> WifiChip::createApIfaceInternal() { if (current_mode_id_ != kApChipModeId || ap_iface_.get()) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } std::string ifname = legacy_hal_.lock()->getApIfaceName(); ap_iface_ = new WifiApIface(ifname, legacy_hal_); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) { LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; } } return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};}

 

wifi.cppWifi::Wifi()    : legacy_hal_(new legacy_hal::WifiLegacyHal()),      mode_controller_(new mode_controller::WifiModeController()),      run_state_(RunState::STOPPED) {}WifiStatus Wifi::startInternal() {  if (run_state_ == RunState::STARTED) {    return createWifiStatus(WifiStatusCode::SUCCESS);  } else if (run_state_ == RunState::STOPPING) {    return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,                            "HAL is stopping");  }  WifiStatus wifi_status = initializeLegacyHal();  if (wifi_status.code == WifiStatusCode::SUCCESS) {    // Create the chip instance once the HAL is started.    chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_);    run_state_ = RunState::STARTED;    for (const auto& callback : event_cb_handler_.getCallbacks()) {      if (!callback->onStart().isOk()) {        LOG(ERROR) << "Failed to invoke onStart callback";      };    }    LOG(INFO) << "Wifi HAL started";  } else {    for (const auto& callback : event_cb_handler_.getCallbacks()) {      if (!callback->onFailure(wifi_status).isOk()) {        LOG(ERROR) << "Failed to invoke onFailure callback";      }    }    LOG(ERROR) << "Wifi HAL start failed";  }  return wifi_status;}wifi_legacy_hal.hstd::string WifiLegacyHal::getApIfaceName() {  // Fake name. This interface does not exist in legacy HAL  // API's.  return "ap0";}wifi_ap_iface.hWifiApIface::WifiApIface(    const std::string& ifname,    const std::weak_ptr
legacy_hal) : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}

 

1.2 setupDriverForSoftApMode

/**    * Setup driver for softAp mode via wificond.    * @return An IApInterface as wificond Ap interface binder handler.    * Returns null on failure.    */    public IApInterface setupDriverForSoftApMode() {        Log.d(TAG, "Setting up driver for soft ap mode");        mWificond = mWifiInjector.makeWificond();        if (mWificond == null) {            Log.e(TAG, "Failed to get reference to wificond");            return null;        }        IApInterface apInterface = null;        try {            apInterface = mWificond.createApInterface();        } catch (RemoteException e1) {            Log.e(TAG, "Failed to get IApInterface due to remote exception");            return null;        }        if (apInterface == null) {            Log.e(TAG, "Could not get IApInterface instance from wificond");            return null;        }        Binder.allowBlocking(apInterface.asBinder());        // Refresh Handlers        mApInterface = apInterface;        return apInterface;    }

/system/connectivity/wificond/server.cpp

Status Server::createApInterface(sp
* created_interface) { InterfaceInfo interface; if (!SetupInterface(&interface)) { return Status::ok(); // Logging was done internally } unique_ptr
ap_interface(new ApInterfaceImpl( interface.name, interface.index, netlink_utils_, if_tool_.get(), hostapd_manager_.get())); *created_interface = ap_interface->GetBinder(); ap_interfaces_.push_back(std::move(ap_interface)); BroadcastApInterfaceReady(ap_interfaces_.back()->GetBinder()); return Status::ok();}bool Server::SetupInterface(InterfaceInfo* interface) { if (!ap_interfaces_.empty() || !client_interfaces_.empty()) { // In the future we may support multiple interfaces at once. However, // today, we support just one. LOG(ERROR) << "Cannot create AP interface when other interfaces exist"; return false; } if (!RefreshWiphyIndex()) { return false; } netlink_utils_->SubscribeRegDomainChange( wiphy_index_, std::bind(&Server::OnRegDomainChanged, this, _1)); interfaces_.clear(); if (!netlink_utils_->GetInterfaces(wiphy_index_, &interfaces_)) { LOG(ERROR) << "Failed to get interfaces info from kernel"; return false; } for (const auto& iface : interfaces_) { // Some kernel/driver uses station type for p2p interface. // In that case we can only rely on hard-coded name to exclude // p2p interface from station interfaces. // Currently NAN interfaces also use station type. // We should blacklist NAN interfaces as well. if (iface.name != "p2p0" && !android::base::StartsWith(iface.name, "aware_data")) { *interface = iface; return true; } }ap_interface_impl.cppApInterfaceImpl::ApInterfaceImpl(const string& interface_name, uint32_t interface_index, NetlinkUtils* netlink_utils, InterfaceTool* if_tool, HostapdManager* hostapd_manager) : interface_name_(interface_name), interface_index_(interface_index), netlink_utils_(netlink_utils), if_tool_(if_tool), hostapd_manager_(hostapd_manager), binder_(new ApInterfaceBinder(this)), number_of_associated_stations_(0) { // This log keeps compiler happy. LOG(DEBUG) << "Created ap interface " << interface_name_ << " with index " << interface_index_; netlink_utils_->SubscribeStationEvent( interface_index_, std::bind(&ApInterfaceImpl::OnStationEvent, this, _1, _2));}

 

1.3 SoftApManager.start

mSoftApManager = mWifiInjector.makeSoftApManager(mNwService,                                                             new SoftApListener(),                                                             apInterface,                                                             config.getWifiConfiguration());            mSoftApManager.start();
/**     * Create a SoftApManager.     * @param nmService NetworkManagementService allowing SoftApManager to listen for interface     * changes     * @param listener listener for SoftApManager     * @param apInterface network interface to start hostapd against     * @param config softAp WifiConfiguration     * @return an instance of SoftApManager     */    public SoftApManager makeSoftApManager(INetworkManagementService nmService,                                           SoftApManager.Listener listener,                                           IApInterface apInterface,                                           WifiConfiguration config) {        return new SoftApManager(mWifiServiceHandlerThread.getLooper(),                                 mWifiNative, mCountryCode.getCountryCode(),                                 listener, apInterface, nmService,                                 mWifiApConfigStore, config, mWifiMetrics);    }

 

/**     * Start soft AP with the supplied config.     */    public void start() {        mStateMachine.sendMessage(SoftApStateMachine.CMD_START, mApConfig);    }

SoftApManager也是一个状态机

SoftApStateMachine(Looper looper) {            super(TAG, looper);            addState(mIdleState);            addState(mStartedState);            setInitialState(mIdleState);            start();        }

IdleState处理CMD_START消息

private class IdleState extends State {            @Override            public void enter() {                mDeathRecipient.unlinkToDeath();                unregisterObserver();            }            @Override            public boolean processMessage(Message message) {                switch (message.what) {                    case CMD_START:                        updateApState(WifiManager.WIFI_AP_STATE_ENABLING, 0);                        if (!mDeathRecipient.linkToDeath(mApInterface.asBinder())) {                            mDeathRecipient.unlinkToDeath();                            updateApState(WifiManager.WIFI_AP_STATE_FAILED,                                    WifiManager.SAP_START_FAILURE_GENERAL);                            mWifiMetrics.incrementSoftApStartResult(                                    false, WifiManager.SAP_START_FAILURE_GENERAL);                            break;                        }                        try {                            mNetworkObserver = new NetworkObserver(mApInterface.getInterfaceName());                            mNwService.registerObserver(mNetworkObserver);                        } catch (RemoteException e) {                            mDeathRecipient.unlinkToDeath();                            unregisterObserver();                            updateApState(WifiManager.WIFI_AP_STATE_FAILED,                                          WifiManager.SAP_START_FAILURE_GENERAL);                            mWifiMetrics.incrementSoftApStartResult(                                    false, WifiManager.SAP_START_FAILURE_GENERAL);                            break;                        }                        int result = startSoftAp((WifiConfiguration) message.obj);                        if (result != SUCCESS) {                            int failureReason = WifiManager.SAP_START_FAILURE_GENERAL;                            if (result == ERROR_NO_CHANNEL) {                                failureReason = WifiManager.SAP_START_FAILURE_NO_CHANNEL;                            }                            mDeathRecipient.unlinkToDeath();                            unregisterObserver();                            updateApState(WifiManager.WIFI_AP_STATE_FAILED, failureReason);                            mWifiMetrics.incrementSoftApStartResult(false, failureReason);                            break;                        }                        transitionTo(mStartedState);                        break;

startSoftAp

/**     * Start a soft AP instance with the given configuration.     * @param config AP configuration     * @return integer result code     */    private int startSoftAp(WifiConfiguration config) {        if (config == null || config.SSID == null) {            Log.e(TAG, "Unable to start soft AP without valid configuration");            return ERROR_GENERIC;        }        // Make a copy of configuration for updating AP band and channel.        WifiConfiguration localConfig = new WifiConfiguration(config);        int result = ApConfigUtil.updateApChannelConfig(                mWifiNative, mCountryCode,                mWifiApConfigStore.getAllowed2GChannel(), localConfig);        if (result != SUCCESS) {            Log.e(TAG, "Failed to update AP band and channel");            return result;        }        // Setup country code if it is provided.        if (mCountryCode != null) {            // Country code is mandatory for 5GHz band, return an error if failed to set            // country code when AP is configured for 5GHz band.            if (!mWifiNative.setCountryCodeHal(mCountryCode.toUpperCase(Locale.ROOT))                    && config.apBand == WifiConfiguration.AP_BAND_5GHZ) {                Log.e(TAG, "Failed to set country code, required for setting up "                        + "soft ap in 5GHz");                return ERROR_GENERIC;            }        }        int encryptionType = getIApInterfaceEncryptionType(localConfig);        if (localConfig.hiddenSSID) {            Log.d(TAG, "SoftAP is a hidden network");        }        try {            // Note that localConfig.SSID is intended to be either a hex string or "double quoted".            // However, it seems that whatever is handing us these configurations does not obey            // this convention.            boolean success = mApInterface.writeHostapdConfig(                    localConfig.SSID.getBytes(StandardCharsets.UTF_8), localConfig.hiddenSSID,                    localConfig.apChannel, encryptionType,                    (localConfig.preSharedKey != null)                            ? localConfig.preSharedKey.getBytes(StandardCharsets.UTF_8)                            : new byte[0]);            if (!success) {                Log.e(TAG, "Failed to write hostapd configuration");                return ERROR_GENERIC;            }            success = mApInterface.startHostapd();            if (!success) {                Log.e(TAG, "Failed to start hostapd.");                return ERROR_GENERIC;            }        } catch (RemoteException e) {            Log.e(TAG, "Exception in starting soft AP: " + e);        }        Log.d(TAG, "Soft AP is started");        return SUCCESS;    }

ap_interface_binder.cpp

binder::Status ApInterfaceBinder::writeHostapdConfig(    const std::vector
& ssid, bool is_hidden, int32_t channel, int32_t binder_encryption_type, const std::vector
& passphrase, bool* out_success) { *out_success = false; if (!impl_) { LOG(WARNING) << "Cannot set config on dead ApInterface."; return binder::Status::ok(); } HostapdManager::EncryptionType encryption_type; switch (binder_encryption_type) { case IApInterface::ENCRYPTION_TYPE_NONE: encryption_type = HostapdManager::EncryptionType::kOpen; break; case IApInterface::ENCRYPTION_TYPE_WPA: encryption_type = HostapdManager::EncryptionType::kWpa; break; case IApInterface::ENCRYPTION_TYPE_WPA2: encryption_type = HostapdManager::EncryptionType::kWpa2; break; default: LOG(ERROR) << "Unknown encryption type: " << binder_encryption_type; return binder::Status::ok(); } *out_success = impl_->WriteHostapdConfig( ssid, is_hidden, channel, encryption_type, passphrase); return binder::Status::ok();}

 

ap_interface_impl.cpp

bool ApInterfaceImpl::WriteHostapdConfig(const vector
& ssid, bool is_hidden, int32_t channel, EncryptionType encryption_type, const vector
& passphrase) { string config = hostapd_manager_->CreateHostapdConfig( interface_name_, ssid, is_hidden, channel, encryption_type, passphrase); if (config.empty()) { return false; } return hostapd_manager_->WriteHostapdConfig(config);}

hostapd_manager.cpp

bool HostapdManager::WriteHostapdConfig(const string& config) {  // Remove hostapd.conf because its file owner might be system  // in previous OS and chmod fails in that case.  RemoveFileIfExists(kHostapdConfigFilePath);  if (!WriteStringToFile(config, kHostapdConfigFilePath,                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,                         AID_WIFI, AID_WIFI)) {    int error = errno;    LOG(ERROR) << "Cannot write hostapd config to \""               << kHostapdConfigFilePath << "\": " << strerror(error);    struct stat st;    int result = stat(kHostapdConfigFilePath, &st);    if (result == 0) {      LOG(ERROR) << "hostapd config file uid: "<< st.st_uid << ", gid: " << st.st_gid                 << ", mode: " << st.st_mode;    } else {      LOG(ERROR) << "Error calling stat() on hostapd config file: " << strerror(errno);    }    return false;  }  return true;}

startHostapd

ap_interface_binder.cppbinder::Status ApInterfaceBinder::startHostapd(bool* out_success) {  *out_success = false;  if (!impl_) {    LOG(WARNING) << "Cannot start hostapd on dead ApInterface.";    return binder::Status::ok();  }  *out_success = impl_->StartHostapd();  return binder::Status::ok();}ap_interface_impl.cppbool ApInterfaceImpl::StartHostapd() {  return hostapd_manager_->StartHostapd();}hostapd_manager.cppconst char kHostapdServiceName[] = "hostapd";bool HostapdManager::StartHostapd() {  if (property_set("ctl.start", kHostapdServiceName) != 0) {    LOG(ERROR) << "Failed to start SoftAP";    return false;  }  LOG(DEBUG) << "SoftAP started successfully";  return true;}

和supplicant类似通过ctl.start将hostapd进程启动起来。

 

2. 总结

 

转载地址:https://jiatai.blog.csdn.net/article/details/82556109 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:(九十三) Android O 连接WiFi AP流程梳理续——保存网络
下一篇:(九十一) Ubuntu 16.04 安装wireshark

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月25日 19时46分10秒