鸿蒙 WiFi 扫描流程(1)

上一篇记录了WiFi 的打开流程,这里我们继续看,WiFi使能后,如何发起扫描?代码还是用的 鸿蒙OpenHarmony4.0基线代码。

foundation/communication/wifi/wifi/services/wifi_standard/wifi_hal/wifi_hal_sta_interface.c

WifiErrorNo Start(void)
{
    LOGI("Ready to start wifi");
    if (StartSupplicant() != WIFI_HAL_SUCCESS) {
        LOGE("wpa_supplicant start failed!");
        return WIFI_HAL_OPEN_SUPPLICANT_FAILED;
    }
    LOGI("wpa_supplicant start successfully!");

    if (AddWpaIface(0) != WIFI_HAL_SUCCESS) {
        LOGE("Failed to add wpa interface!");
        StopWpaAndWpaHal(0);
        return WIFI_HAL_CONN_SUPPLICANT_FAILED;
    }

    if (ConnectSupplicant() != WIFI_HAL_SUCCESS) {
        LOGE("SupplicantHal connect wpa_supplicant failed!");
        StopWpaAndWpaHal(0);
        return WIFI_HAL_CONN_SUPPLICANT_FAILED;
    }
#ifdef HDI_INTERFACE_SUPPORT
    if (HdiStart() != WIFI_HAL_SUCCESS) {
        LOGE("[STA] Start hdi failed!");
        return WIFI_HAL_FAILED;
    }
    if (RegisterHdiStaCallbackEvent() != WIFI_HAL_SUCCESS) {
        LOGE("[STA] Start RegisterHdiStaCallbackEvent failed!");
        return WIFI_HAL_FAILED;
    }
#endif
    LOGI("Start wifi successfully");
    return WIFI_HAL_SUCCESS;
}

上段代码我们知道,如果使能成功后就会返回 WIFI_HAL_SUCCESS,那看下那个地方去判断这个返回值,这里的 WIFI_HAL_SUCCESS 值是 0,表示 Success;
foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp

void StaStateMachine::StartWifiProcess()
{
    WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::ENABLING));
    staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_OPENING);
    int res;
    if (WifiOprMidState::RUNNING == WifiConfigCenter::GetInstance().GetWifiScanOnlyMidState()) {
        res = static_cast<int>(WIFI_IDL_OPT_OK);
    } else {
        res = WifiStaHalInterface::GetInstance().StartWifi();     ---> 此时成功后,返回值是 0}

    if (res == static_cast<int>(WIFI_IDL_OPT_OK)) {    ---> 就走到这里来了
        WIFI_LOGI("Start wifi successfully!");
        if (WifiStaHalInterface::GetInstance().WpaAutoConnect(false) != WIFI_IDL_OPT_OK) {
            WIFI_LOGI("The automatic Wpa connection is disabled failed.");
        }

        /* callback the InterfaceService that wifi is enabled successfully. */        ---> 通知给相应的接口服务
        WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::ENABLED));
        staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_SUCCEED);
        /* Sets the MAC address of WifiSettings. */
        std::string mac;
        if ((WifiStaHalInterface::GetInstance().GetStaDeviceMacAddress(mac)) == WIFI_IDL_OPT_OK) {
            WifiSettings::GetInstance().SetMacAddress(mac);
            std::string realMacAddress;
            WifiSettings::GetInstance().GetRealMacAddress(realMacAddress);
            if (realMacAddress.empty()) {
                WifiSettings::GetInstance().SetRealMacAddress(mac);
            }
        } else {
            WIFI_LOGI("GetStaDeviceMacAddress failed!");
        }
#ifndef OHOS_ARCH_LITE
        WIFI_LOGI("Register netsupplier");
        WifiNetAgent::GetInstance().OnStaMachineWifiStart();
#endif
        /* Initialize Connection Information. */
        InitWifiLinkedInfo();
        InitLastWifiLinkedInfo();
        WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo);
        SyncDeviceConfigToWpa();
#ifndef OHOS_ARCH_LITE
        ChipCapability::GetInstance().InitializeChipCapability();
#endif
        /* The current state of StaStateMachine transfers to SeparatedState after
         * enable supplicant.
         */
        SwitchState(pSeparatedState);      ---> 切换状态机
    } else {
        /* Notify the InterfaceService that wifi is failed to enable wifi. */
        LOGE("StartWifi failed, and errcode is %d.", res);
        WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::DISABLED));
        WifiSettings::GetInstance().SetUserLastSelectedNetworkId(INVALID_NETWORK_ID);
        staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_FAILED);
    }
}

这里我们看如何callback 的

// 更新状态
WifiSettings::GetInstance().SetWifiState(static_cast<int>(WifiState::ENABLED));
// 主要找到 staCallback 里面的 OnStaOpenRes 方法
staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_SUCCEED);
// 我们看下这个staCallback 是何时被赋值的,在 sta_state_machine.cpp 类里面找到如下:
void StaStateMachine::RegisterStaServiceCallback(const StaServiceCallback &callbacks)
{
    WIFI_LOGI("RegisterStaServiceCallback.");
    staCallback = callbacks;
}
// 那何时注册的呢?在往回找:
//foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_service.cpp
ErrCode StaService::InitStaService(const StaServiceCallback &callbacks)
{
	 RegisterStaServiceCallback(callbacks);
}
void StaService::RegisterStaServiceCallback(const StaServiceCallback &callbacks) const
{
    LOGI("Enter StaService::RegisterStaServiceCallback.");
    if (pStaStateMachine == nullptr) {
        LOGE("pStaStateMachine is null.\n");
        return;
    }
    pStaStateMachine->RegisterStaServiceCallback(callbacks);    ---> 注册到上面的  sta_state_machine.cpp 类里面
}
// 再往回找,看谁调用StaService::InitStaService 方法,这里我就省去流程了,最终可以发现在 wifi_manager.cpp 类里面
// 传的参数都是  WifiManager::GetInstance().GetStaCallback(),所以直接看WifiManager里面的GetStaCallback方法
StaServiceCallback WifiManager::GetStaCallback()
{
    return mStaCallback;       ---> 就是这个
}

// staCallback.OnStaOpenRes(OperateResState::OPEN_WIFI_SUCCEED); 也就是回掉WifiManager::mStaCallback::OnStaOpenRes方法
// foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_manager.cpp
void WifiManager::InitStaCallback(void)
{
    mStaCallback.OnStaOpenRes = DealStaOpenRes;      ---》 初始化成这个,那我们就看这个
    mStaCallback.OnStaCloseRes = DealStaCloseRes;
    mStaCallback.OnStaConnChanged = DealStaConnChanged;
    mStaCallback.OnWpsChanged = DealWpsChanged;
    mStaCallback.OnStaStreamChanged = DealStreamChanged;
    mStaCallback.OnStaRssiLevelChanged = DealRssiChanged;
    return;
}
// OPEN_WIFI_SUCCEED 值是 1
void WifiManager::DealStaOpenRes(OperateResState state)
{   //  OPEN_WIFI_OPENING = 0, OPEN_WIFI_SUCCEED = 1, OPEN_WIFI_FAILED = 2;
    WIFI_LOGI("Enter DealStaOpenRes: %{public}d", static_cast<int>(state));
    WifiEventCallbackMsg cbMsg;
    cbMsg.msgCode = WIFI_CBK_MSG_STATE_CHANGE;
    if (state == OperateResState::OPEN_WIFI_OPENING) {
        cbMsg.msgData = static_cast<int>(WifiState::ENABLING);
        WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
        return;
    }
    if ((state == OperateResState::OPEN_WIFI_FAILED) || (state == OperateResState::OPEN_WIFI_DISABLED)) {
        WIFI_LOGE("DealStaOpenRes:wifi open failed!");
        WifiConfigCenter::GetInstance().SetWifiMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED);
        DealStaCloseRes(state);
        return;
    }

    WIFI_LOGI("DealStaOpenRes:wifi open successfully!");
    WifiConfigCenter::GetInstance().SetWifiMidState(WifiOprMidState::OPENING, WifiOprMidState::RUNNING);
    WifiConfigCenter::GetInstance().SetStaLastRunState(true);
    if (WifiConfigCenter::GetInstance().GetAirplaneModeState() == MODE_STATE_OPEN) {
        WifiConfigCenter::GetInstance().SetWifiStateWhenAirplaneMode(true);
    }
#ifdef FEATURE_P2P_SUPPORT
    WifiOprMidState p2pState = WifiConfigCenter::GetInstance().GetP2pMidState();
    WIFI_LOGI("DealStaOpenRes, current p2p state:%{public}d", p2pState);
    if (p2pState == WifiOprMidState::CLOSED) {
        WifiManager::GetInstance().AutoStartP2pService(AutoStartOrStopServiceReason::TYRTO_ENABLE_P2P_WHEN_WIFI_OPENED);
    }
#endif
    cbMsg.msgData = static_cast<int>(WifiState::ENABLED);
    WifiInternalEventDispatcher::GetInstance().AddBroadCastMsg(cbMsg);
    AutoStartEnhanceService();
    CheckAndStartScanService();    ---> 和扫描相关的

    if (WifiSettings::GetInstance().CheckScanOnlyAvailable() &&
        WifiManager::GetInstance().GetLocationModeByDatashare(WIFI_SCAN_ABILITY_ID)) {
        WifiConfigCenter::GetInstance().SetWifiScanOnlyMidState(WifiOprMidState::RUNNING);
    }
}

// 看扫描相关的 CheckAndStartScanService 方法:
void WifiManager::CheckAndStartScanService(void)
{
    WifiOprMidState scanState = WifiConfigCenter::GetInstance().GetScanMidState();
    WIFI_LOGI("CheckAndStartScanService scanState: %{public}d", static_cast<int>(scanState));
    if (scanState != WifiOprMidState::CLOSED) {
        /* If the scanning function is enabled when the STA is not enabled, you need to start the scheduled
             scanning function immediately when the STA is enabled. */
        IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst();
        if (pService != nullptr) {
            pService->OnClientModeStatusChanged(static_cast<int>(OperateResState::DISCONNECT_DISCONNECTED));
        }
        return;
    }
    if (!WifiConfigCenter::GetInstance().SetScanMidState(scanState, WifiOprMidState::OPENING)) {
        WIFI_LOGW("Failed to set scan mid state opening! may be other activity has been operated");
        return;
    }
    ErrCode errCode = WIFI_OPT_FAILED;
    do {
        if (WifiServiceManager::GetInstance().CheckAndEnforceService(WIFI_SERVICE_SCAN) < 0) {
            WIFI_LOGE("Load %{public}s service failed!", WIFI_SERVICE_SCAN);
            break;
        }
        IScanService *pService = WifiServiceManager::GetInstance().GetScanServiceInst();    ---> 这个就是scan_interface.cpp
        if (pService == nullptr) {
            WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_SCAN);
            break;
        }
        errCode = pService->RegisterScanCallbacks(WifiManager::GetInstance().GetScanCallback());
        if (errCode != WIFI_OPT_SUCCESS) {
            WIFI_LOGE("Register scan service callback failed!");
            break;
        }
        errCode = pService->Init();     ----> 主要看下这个
        if (errCode != WIFI_OPT_SUCCESS) {
            WIFI_LOGE("init scan service failed, ret %{public}d!", static_cast<int>(errCode));
            break;
        }
        IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
        if (pEnhanceService == nullptr) {
            WIFI_LOGE("Create %{public}s service failed!", WIFI_SERVICE_ENHANCE);
            break;
        }
        errCode = pService->SetEnhanceService(pEnhanceService);
        if (errCode != WIFI_OPT_SUCCESS) {
            WIFI_LOGE("SetEnhanceService failed, ret %{public}d!", static_cast<int>(errCode));
            break;
        }
    } while (0);
    if (errCode != WIFI_OPT_SUCCESS) {
        WifiConfigCenter::GetInstance().SetScanMidState(WifiOprMidState::OPENING, WifiOprMidState::CLOSED);
        WifiServiceManager::GetInstance().UnloadService(WIFI_SERVICE_SCAN);
    }
    return;
}

pService->Init() 看下初始化扫描服务foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_interface.cpp

ErrCode ScanInterface::Init()
{
    WIFI_LOGI("Enter ScanInterface::Init.\n");
    pScanService = new (std::nothrow)ScanService();     ---> 创建可一个 ScanService,初始化参数
    if (pScanService == nullptr) {
        WIFI_LOGE("New ScanService failed.\n");
        return WIFI_OPT_INVALID_PARAM;
    }

    if (!(pScanService->InitScanService(mScanSerivceCallbacks))) {   ---> 对应上面传下来的注册参数
        WIFI_LOGE("InitScanService failed.\n");
        delete pScanService;
        pScanService = nullptr;
        return WIFI_OPT_INVALID_PARAM;
    }
    return WIFI_OPT_SUCCESS;
}

//foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp
bool ScanService::InitScanService(const IScanSerivceCallbacks &scanSerivceCallbacks)
{
    WIFI_LOGI("Enter ScanService::InitScanService.\n");

    mScanSerivceCallbacks = scanSerivceCallbacks;
    pScanStateMachine = new (std::nothrow) ScanStateMachine();    ---> 状态机
    if (pScanStateMachine == nullptr) {
        WIFI_LOGE("Alloc pScanStateMachine failed.\n");
        return false;
    }

    if (!pScanStateMachine->InitScanStateMachine()) {
        WIFI_LOGE("InitScanStateMachine failed.\n");
        return false;
    }

    if (!pScanStateMachine->EnrollScanStatusListener(
        std::bind(&ScanService::HandleScanStatusReport, this, std::placeholders::_1))) {
        WIFI_LOGE("ScanStateMachine_->EnrollScanStatusListener failed.\n");
        return false;
    }
    pScanMonitor = new (std::nothrow) ScanMonitor();     ---> 消息监视
    if (pScanMonitor == nullptr) {
        WIFI_LOGE("Alloc pScanMonitor failed.\n");
        return false;
    }

    if (!pScanMonitor->InitScanMonitor()) {
        WIFI_LOGE("InitScanMonitor failed.\n");
        return false;
    }
#ifndef OHOS_ARCH_LITE
    if (standByListerner.Init()) {
        WIFI_LOGE("standByListerner Init failed.");
    }
#endif

    if ((WifiStaHalInterface::GetInstance().GetSupportFrequencies(SCAN_BAND_24_GHZ, freqs2G) != WIFI_IDL_OPT_OK) ||
        (WifiStaHalInterface::GetInstance().GetSupportFrequencies(SCAN_BAND_5_GHZ, freqs5G) != WIFI_IDL_OPT_OK) ||
        (WifiStaHalInterface::GetInstance().GetSupportFrequencies(SCAN_BAND_5_GHZ_DFS_ONLY, freqsDfs) !=
        WIFI_IDL_OPT_OK)) {
        WIFI_LOGE("GetSupportFrequencies failed.\n");
    }

    ChannelsTable chanTbs;
    (void)WifiSettings::GetInstance().GetValidChannels(chanTbs);
    if (chanTbs[BandType::BAND_2GHZ].size() == 0) {
        WIFI_LOGI("Update valid channels!");
        std::vector<int32_t> supp2Gfreqs(freqs2G.begin(), freqs2G.end());
        std::vector<int32_t> supp5Gfreqs(freqs5G.begin(), freqs5G.end());
        for (auto iter = supp2Gfreqs.begin(); iter != supp2Gfreqs.end(); iter++) {
            int32_t channel = FrequencyToChannel(*iter);
            if (channel == INVALID_FREQ_OR_CHANNEL) {
                continue;
            }
            chanTbs[BandType::BAND_2GHZ].push_back(channel);
        }
        for (auto iter = supp5Gfreqs.begin(); iter != supp5Gfreqs.end(); iter++) {
            int32_t channel = FrequencyToChannel(*iter);
            if (channel == INVALID_FREQ_OR_CHANNEL) {
                continue;
            }
            chanTbs[BandType::BAND_5GHZ].push_back(channel);
        }
        if (WifiSettings::GetInstance().SetValidChannels(chanTbs)) {
            WIFI_LOGE("%{public}s, fail to SetValidChannels", __func__);
        }
    }
    pScanMonitor->SetScanStateMachine(pScanStateMachine);
    pScanStateMachine->SendMessage(static_cast<int>(CMD_SCAN_PREPARE));    ---> 状态机里面处理 CMD_SCAN_PREPARE
    GetScanControlInfo();

    return true;
}

我们到状态机里面看下如何处理这个消息 CMD_SCAN_PREPARE
foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_state_machine.cpp

bool ScanStateMachine::InitState::ExecuteStateMsg(InternalMessage *msg)
{
    WIFI_LOGI("Enter ScanStateMachine::InitState::ExecuteStateMsg.\n");
    if (msg == nullptr) {
        WIFI_LOGE("msg is null.\n");
        return true;
    }

    switch (msg->GetMessageName()) {
        case CMD_SCAN_PREPARE:
            LoadDriver();   ---> 执行这个方法
            return true;
            
// 看下LoadDriver() 方法:
void ScanStateMachine::InitState::LoadDriver()
{
    WIFI_LOGI("Enter ScanStateMachine::LoadDriver.\n");
    pScanStateMachine->SwitchState(pScanStateMachine->hardwareReadyState);   ---> 状态切换为 HardwareReadyState
    pScanStateMachine->ReportStatusChange(SCAN_STARTED_STATUS);     ---> 上报 SCAN_STARTED_STATUS = 0,  /* Started successfully */
    WIFI_LOGI("Start Scan Service Success.\n");
}

void ScanStateMachine::ReportStatusChange(ScanStatus status)
{
    WIFI_LOGI("Enter ScanStateMachine::ReportStatusChange.\n");
    ScanStatusReport scanStatusReport;
    scanStatusReport.status = status;
    if (scanStatusReportHandler) {
        scanStatusReportHandler(scanStatusReport);     ---> 看这个
    }
}
// foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp
void ScanService::HandleScanStatusReport(ScanStatusReport &scanStatusReport)
{
    WIFI_LOGI("Enter ScanService::HandleScanStatusReport.\n");

    switch (scanStatusReport.status) {
        case SCAN_STARTED_STATUS: {
            if (pScanStateMachine == nullptr) {
                WIFI_LOGE("HandleScanStatusReport-SCAN_STARTED_STATUS pScanStateMachine is null\n");
                return;
            }
            scanStartedFlag = true;
            /* Pno scan maybe has started, stop it first. */
            pScanStateMachine->SendMessage(CMD_STOP_PNO_SCAN);    ---》 先停止PNO扫描
            mScanSerivceCallbacks.OnScanStartEvent();    ---> 更新下状态
            SystemScanProcess(true);    ---> 看这个方法
            break;
        }
// 跟着流程继续往下看: 
void ScanService::SystemScanProcess(bool scanAtOnce)
{
    WIFI_LOGI("Enter ScanService::SystemScanProcess, scanAtOnce:%{public}d.", scanAtOnce);
    StopSystemScan();

    int state = WifiSettings::GetInstance().GetScreenState();
    WIFI_LOGI("Screen state(1:OPEN, 2:CLOSE): %{public}d.", state);   ---> 屏幕状态决定哪种扫描模式
    if (state == MODE_STATE_OPEN) {
        {
            std::unique_lock<std::mutex> lock(scanControlInfoMutex);
            int i = 0;
            for (auto iter = scanControlInfo.scanIntervalList.begin(); iter != scanControlInfo.scanIntervalList.end(); ++iter) {
                if (iter->scanScene ==SCAN_SCENE_ALL && iter->scanMode ==ScanMode::SYSTEM_TIMER_SCAN && iter->isSingle ==false) {
                    WIFI_LOGI("iter[%{public}d]: intervalMode:%{public}d, interval:%{public}d, count:%{public}d",
                        i++, iter->intervalMode, iter->interval, iter->count);
                    systemScanIntervalMode.scanIntervalMode.intervalMode = iter->intervalMode;
                    systemScanIntervalMode.scanIntervalMode.interval = iter->interval;
                    systemScanIntervalMode.scanIntervalMode.count = iter->count;
                    systemScanIntervalMode.expScanCount = 0;
                }
            }
        }
        // 上面的参数配置好后,执行系统调度扫描
        StartSystemTimerScan(scanAtOnce);
    } else {
        if (!BeginPnoScan()) {
            WIFI_LOGE("BeginPnoScan failed.");
            return;
        }
    }
    return;
}

看下扫描模式有哪些,这里的是 SYSTEM_TIMER_SCAN

enum class ScanMode {
    APP_FOREGROUND_SCAN = 0, /* Scan initiated by the foreground application */
    APP_BACKGROUND_SCAN = 1, /* Scan initiated by background applications */
    SYS_FOREGROUND_SCAN = 2, /* System foreground scan */
    SYS_BACKGROUND_SCAN = 3, /* System background scan */
    ALL_EXTERN_SCAN = 4,     /* All external scans, including the first four */
    PNO_SCAN = 5,            /* PNO scan */
    SYSTEM_TIMER_SCAN = 6,   /* Scheduled system scan */
    ANYTIME_SCAN = 7,        /* Scan at any time */
    BAND_24GHZ_SCAN = 8,     /* 2.4 GHz scan */
    BAND_5GHZ_SCAN = 9,      /* 5G scan */
    SCAN_MODE_MAX            /* Invalid value */

接着看上面提到的这个方法: StartSystemTimerScan(scanAtOnce);

void ScanService::StartSystemTimerScan(bool scanAtOnce)
{
    WIFI_LOGI("Enter ScanService::StartSystemTimerScan, scanAtOnce: %{public}d.", scanAtOnce);
    ErrCode rlt = ApplyScanPolices(ScanType::SCAN_TYPE_SYSTEMTIMER);    ---> 决定是否允许以及如何对Wi-Fi进行扫描操作的一些判断
    if (rlt != WIFI_OPT_SUCCESS) {
        return;
    }

    struct timespec times = { 0, 0 };
    clock_gettime(CLOCK_MONOTONIC, &times);
    int64_t nowTime =
        static_cast<int64_t>(times.tv_sec) * SECOND_TO_MILLI_SECOND + times.tv_nsec / SECOND_TO_MICRO_SECOND;
    int sinceLastScan = 0;
    if (lastSystemScanTime != 0) {
        sinceLastScan = nowTime - lastSystemScanTime;
    }

    /*
     * The scan is performed immediately, the first scan is required,
     * or the time since the last scan is longer than the scan interval.
     */
    int scanTime = SYSTEM_SCAN_INIT_TIME;
    if (systemScanIntervalMode.scanIntervalMode.interval > 0) {
        scanTime = systemScanIntervalMode.scanIntervalMode.interval;
    }
    if (scanAtOnce || (lastSystemScanTime == 0) || (sinceLastScan >= systemScanIntervalMode.scanIntervalMode.interval)) {
        if (Scan(false) != WIFI_OPT_SUCCESS) {      ---> 发起扫描
            WIFI_LOGE("Scan failed.");
        }
        lastSystemScanTime = nowTime;
    } else {
        scanTime = systemScanIntervalMode.scanIntervalMode.interval - sinceLastScan;
    }
    // 上面都是对扫描时间的一些逻辑
    WIFI_LOGI("StartSystemTimerScan, scanTime: %{public}d,  interval:%{public}d,  count:%{public}d",
        scanTime,
        systemScanIntervalMode.scanIntervalMode.interval,
        systemScanIntervalMode.scanIntervalMode.count);
    pScanStateMachine->StartTimer(static_cast<int>(SYSTEM_SCAN_TIMER), scanTime * SECOND_TO_MILLI_SECOND);   ---》 启动一个定时器
    return;
}

两个参数,前者是实际的扫描时间,后者是最大的扫描时间,这里是10s
pScanStateMachine->StartTimer(static_cast(SYSTEM_SCAN_TIMER), scanTime * SECOND_TO_MILLI_SECOND);
继续看下发起的扫描 Scan(false)
foundation/communication/wifi/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp

ErrCode ScanService::Scan(bool externFlag)
{
    WIFI_LOGI("Enter ScanService::Scan, externFlag:%{public}d.\n", externFlag);      ---> 传下来的是false
    if (!scanStartedFlag) {
        WIFI_LOGE("Scan service has not started.\n");
        return WIFI_OPT_FAILED;
    }

    if (externFlag) {      ---> 这里没有额外的
        ErrCode rlt = ApplyScanPolices(ScanType::SCAN_TYPE_EXTERN);
        if (rlt != WIFI_OPT_SUCCESS) {
            return rlt;
        }
    }

    ScanConfig scanConfig;
    /*
     * Invoke the interface provided by the configuration center to obtain the
     * hidden network list.
     */
    if (!GetHiddenNetworkSsidList(scanConfig.hiddenNetworkSsid)) {       ---> 发现是否有隐藏网络
        WIFI_LOGE("GetHiddenNetworkSsidList failed.\n");
    }

    scanConfig.scanBand = SCAN_BAND_BOTH_WITH_DFS;
    scanConfig.fullScanFlag = true;
    scanConfig.externFlag = externFlag;
    scanConfig.scanStyle = SCAN_TYPE_HIGH_ACCURACY;
    if (!SingleScan(scanConfig)) {                  ---> 发起单词扫描,这个和Android 扫描差不多     
        WIFI_LOGE("SingleScan failed.\n");
        return WIFI_OPT_FAILED;
    }

    return WIFI_OPT_SUCCESS;
}
// 继续看 发起单次扫描:
bool ScanService::SingleScan(ScanConfig &scanConfig)
{
    WIFI_LOGI("Enter ScanService::SingleScan.\n");

#ifndef OHOS_ARCH_LITE
    if (!standByListerner.AllowScan()) {
        WIFI_LOGE("Scan not allowed when device in standby state.\n");
        return WIFI_OPT_FAILED;
    }
#endif

    GetAllowBandFreqsControlInfo(scanConfig.scanBand, scanConfig.scanFreqs);
    if ((scanConfig.scanBand == SCAN_BAND_UNSPECIFIED) && (scanConfig.scanFreqs.empty())) {
        WIFI_LOGE("Have no allowed band or freq.\n");
        return false;
    }

    InterScanConfig interConfig;
    interConfig.fullScanFlag = scanConfig.fullScanFlag;
    interConfig.hiddenNetworkSsid.assign(scanConfig.hiddenNetworkSsid.begin(), scanConfig.hiddenNetworkSsid.end());
    interConfig.scanStyle = scanConfig.scanStyle;

    /* Specified frequency */
    if (scanConfig.scanBand == SCAN_BAND_UNSPECIFIED) {
        interConfig.scanFreqs.assign(scanConfig.scanFreqs.begin(), scanConfig.scanFreqs.end());
        /*
         * When band is SCAN_BAND_BOTH_WITH_DFS, need to scan all frequency,
         * scanFreqs can be empty.
         */
    } else if (scanConfig.scanBand != SCAN_BAND_BOTH_WITH_DFS) {
        /* Converting frequency bands to frequencies. */
        if (!GetBandFreqs(scanConfig.scanBand, interConfig.scanFreqs)) {
            WIFI_LOGE("GetBandFreqs failed.\n");
            return false;
        }
    }

    /* Save the configuration. */
    int requestIndex = StoreRequestScanConfig(scanConfig, interConfig);
    if (requestIndex == MAX_SCAN_CONFIG_STORE_INDEX) {
        WIFI_LOGE("StoreRequestScanConfig failed.\n");
        return false;
    }

    std::unique_lock<std::mutex> lock(scanConfigMapMutex);
    if (pScanStateMachine == nullptr) {
        WIFI_LOGE("pScanStateMachine is null.\n");
        return false;
    }
    /* Construct a message. */
    InternalMessage *interMessage =
        pScanStateMachine->CreateMessage(static_cast<int>(CMD_START_COMMON_SCAN), requestIndex);
    if (interMessage == nullptr) {
        scanConfigMap.erase(requestIndex);
        WIFI_LOGE("CreateMessage failed.\n");
        return false;
    }

    if (!AddScanMessageBody(interMessage, interConfig)) {
        scanConfigMap.erase(requestIndex);
        MessageManage::GetInstance().ReclaimMsg(interMessage);
        WIFI_LOGE("AddScanMessageBody failed.\n");
        return false;
    }
    pScanStateMachine->SendMessage(interMessage);

    return true;
}

这篇文章先记录到这里,下篇文章接着 SingleScan 方法往下看,看如何和HAL交互。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值