android wifi framework创建softap(个人热点)

这是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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值