wifi_request_manager.cc revision 50d7d95f1d8cae0e9c6202086b9bd432adff7bf1
156b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol/* 256b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * Copyright (C) 2016 The Android Open Source Project 356b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * 456b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * Licensed under the Apache License, Version 2.0 (the "License"); 556b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * you may not use this file except in compliance with the License. 656b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * You may obtain a copy of the License at 756b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * 856b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * http://www.apache.org/licenses/LICENSE-2.0 956b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * 1056b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * Unless required by applicable law or agreed to in writing, software 1156b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * distributed under the License is distributed on an "AS IS" BASIS, 1256b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * See the License for the specific language governing permissions and 1456b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol * limitations under the License. 1556b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol */ 1656b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 1756b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol#include <cinttypes> 1856b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 1930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol#include "chre/core/event_loop_manager.h" 2056b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol#include "chre/core/wifi_request_manager.h" 2130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol#include "chre/platform/fatal_error.h" 2256b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol#include "chre/platform/log.h" 2356b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 2456b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignolnamespace chre { 2556b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 2630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew RossignolWifiRequestManager::WifiRequestManager() { 2730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Reserve space for at least one scan monitoring nanoapp. This ensures that 2830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // the first asynchronous push_back will succeed. Future push_backs will be 2930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // synchronous and failures will be returned to the client. 3030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorNanoapps.reserve(1)) { 3130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol FATAL_ERROR("Failed to allocate scan monitoring nanoapps list at startup"); 3230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 3330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 3430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 35bdf404267034f69fc1555ef266d9dd12ba9215eeAndrew Rossignoluint32_t WifiRequestManager::getCapabilities() { 36bdf404267034f69fc1555ef266d9dd12ba9215eeAndrew Rossignol return mPlatformWifi.getCapabilities(); 3756b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol} 3856b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 3930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::configureScanMonitor(Nanoapp *nanoapp, bool enable, 4030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 4130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT(nanoapp); 4230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 4330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = false; 4430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId = nanoapp->getInstanceId(); 45dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol bool hasScanMonitorRequest = nanoappHasScanMonitorRequest(instanceId); 4630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 4730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = addScanMonitorRequestToQueue(nanoapp, enable, cookie); 48dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol } else if (scanMonitorIsInRequestedState(enable, hasScanMonitorRequest)) { 4930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // The scan monitor is already in the requested state. A success event can 5030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // be posted immediately. 5130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = postScanMonitorAsyncResultEvent(instanceId, true /* success */, 5230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol enable, CHRE_ERROR_NONE, cookie); 53dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol } else if (scanMonitorStateTransitionIsRequired(enable, 54dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol hasScanMonitorRequest)) { 5530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = addScanMonitorRequestToQueue(nanoapp, enable, cookie); 5630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (success) { 5730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = mPlatformWifi.configureScanMonitor(enable); 5830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 5930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // TODO: Add a pop_back method. 6030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.remove( 6130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.size() - 1); 6230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to enable the scan monitor for nanoapp instance %" PRIu32, 6330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol instanceId); 6430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 6530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 6630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 6730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor configuration"); 6830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 6930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 7030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 7130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 7230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 7384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::requestScan(Nanoapp *nanoapp, 7484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const chreWifiScanParams *params, 7584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 7684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT(nanoapp); 7784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 7884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = false; 7984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!mScanRequestingNanoappInstanceId.has_value()) { 8084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success = mPlatformWifi.requestScan(params); 8184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (success) { 8284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId = nanoapp->getInstanceId(); 8384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie = cookie; 8484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 8584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 8684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Active wifi scan request made while a request is in flight"); 8784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 8884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 8984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return success; 9084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 9184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 923a34ff2bf5e4afd466abb2b9af26abf719ec34fdAndrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChange(bool enabled, 933a34ff2bf5e4afd466abb2b9af26abf719ec34fdAndrew Rossignol uint8_t errorCode) { 9430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol struct CallbackState { 9530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enabled; 9630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode; 9730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol }; 9830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 99a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto *cbState = memoryAlloc<CallbackState>(); 100a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie if (cbState == nullptr) { 10130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate callback state for scan monitor state change"); 10230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 103a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->enabled = enabled; 104a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->errorCode = errorCode; 10530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 10696f33751ce98a3e64d90373a3a42f88458b3aef0Andrew Rossignol auto callback = [](uint16_t /* eventType */, void *eventData) { 10730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol auto *state = static_cast<CallbackState *>(eventData); 10830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 10930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol .handleScanMonitorStateChangeSync(state->enabled, state->errorCode); 11030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol memoryFree(state); 11130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol }; 11230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 11319b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol bool callbackDeferred = EventLoopManagerSingleton::get()->deferCallback( 114a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie SystemCallbackType::WifiScanMonitorStateChange, cbState, callback); 11519b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol if (!callbackDeferred) { 11619b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol memoryFree(cbState); 11719b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol } 11830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 119cbff0ad0e40b03ea9972e3446f1d238796e07398Andrew Rossignol} 120cbff0ad0e40b03ea9972e3446f1d238796e07398Andrew Rossignol 121d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanResponse(bool pending, 122d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol uint8_t errorCode) { 12384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol struct CallbackState { 12484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool pending; 12584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode; 12684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol }; 12784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 128a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto *cbState = memoryAlloc<CallbackState>(); 129a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie if (cbState == nullptr) { 13084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate callback state for wifi scan response"); 13184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 132a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->pending = pending; 133a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->errorCode = errorCode; 13484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 13596f33751ce98a3e64d90373a3a42f88458b3aef0Andrew Rossignol auto callback = [](uint16_t /* eventType */, void *eventData) { 13684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol auto *state = static_cast<CallbackState *>(eventData); 13784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 13884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol .handleScanResponseSync(state->pending, state->errorCode); 13984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol memoryFree(state); 14084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol }; 14184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 14284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 143a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie SystemCallbackType::WifiRequestScanResponse, cbState, callback); 14484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 145d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 146d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 147d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanEvent(chreWifiScanEvent *event) { 148254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol auto callback = [](uint16_t eventType, void *eventData) { 149254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData); 150254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 151254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol .handleScanEventSync(scanEvent); 152254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol }; 153254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 154254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 155254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol SystemCallbackType::WifiHandleScanEvent, event, callback); 156d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 157d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 15830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsEnabled() const { 15930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return !mScanMonitorNanoapps.empty(); 16030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 16130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 16230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::nanoappHasScanMonitorRequest( 16330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId, size_t *nanoappIndex) const { 16430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol size_t index = mScanMonitorNanoapps.find(instanceId); 16544b56ef8ab3ef4de08f2fc84e469dfb3e84e8d08Andrew Rossignol bool hasScanMonitorRequest = (index != mScanMonitorNanoapps.size()); 16630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (hasScanMonitorRequest && nanoappIndex != nullptr) { 16730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol *nanoappIndex = index; 16830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 16930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 17030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return hasScanMonitorRequest; 17130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 17230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 17330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsInRequestedState( 17430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 17530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return (requestedState == scanMonitorIsEnabled() || (!requestedState 17630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && (!nanoappHasRequest || mScanMonitorNanoapps.size() > 1))); 17730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 17830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 17930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorStateTransitionIsRequired( 18030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 18130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return ((requestedState && mScanMonitorNanoapps.empty()) 18230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol || (!requestedState && nanoappHasRequest 18330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && mScanMonitorNanoapps.size() == 1)); 18430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 18530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 18630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::addScanMonitorRequestToQueue(Nanoapp *nanoapp, 18730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enable, 18830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 18930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol ScanMonitorStateTransition scanMonitorStateTransition; 19030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.nanoappInstanceId = nanoapp->getInstanceId(); 19130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.cookie = cookie; 19230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.enable = enable; 19330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 19430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = mScanMonitorStateTransitions.push(scanMonitorStateTransition); 19530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 19630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGW("Too many scan monitor state transitions"); 19730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 19830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 19930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 20030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 20130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 20230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::updateNanoappScanMonitoringList(bool enable, 20330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId) { 20430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = true; 20550d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 20650d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .findNanoappByInstanceId(instanceId); 207254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 208254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Failed to update scan monitoring list for " 209254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "non-existent nanoapp"); 21030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 211254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol size_t nanoappIndex; 212254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol bool hasExistingRequest = nanoappHasScanMonitorRequest(instanceId, 213254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol &nanoappIndex); 214254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (enable) { 215254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!hasExistingRequest) { 216254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = nanoapp->registerForBroadcastEvent( 217254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_EVENT_WIFI_SCAN_RESULT); 218254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!success) { 219254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Failed to register nanoapp for wifi scan events"); 220254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 221254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // The scan monitor was successfully enabled for this nanoapp and 222254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // there is no existing request. Add it to the list of scan monitoring 223254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // nanoapps. 224254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = mScanMonitorNanoapps.push_back(instanceId); 225254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!success) { 226254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 227254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Failed to add nanoapp to the list of scan monitoring " 228254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "nanoapps"); 229254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 230254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 231254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 23230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 233254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!hasExistingRequest) { 234254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = false; 235254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Received a scan monitor state change for a non-existent nanoapp"); 236254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 237254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // The scan monitor was successfully disabled for a previously enabled 238254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // nanoapp. Remove it from the list of scan monitoring nanoapps. 239254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanMonitorNanoapps.erase(nanoappIndex); 240254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 241254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 24230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 24330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 24430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 24530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 24630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 24730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 24830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::postScanMonitorAsyncResultEvent( 24930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 25030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 25130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Allocate and post an event to the nanoapp requesting wifi. 25230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool eventPosted = false; 25330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success || updateNanoappScanMonitoringList(enable, nanoappInstanceId)) { 25430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 25530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (event == nullptr) { 25630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate wifi scan monitor async result event"); 25730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 25830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR; 25930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->success = success; 26030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->errorCode = errorCode; 26130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->reserved = 0; 26230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->cookie = cookie; 26330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 26430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Post the event. 26550d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 26650d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .postEvent(CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback, 26750d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 2687e2da194710e593ad1248d4fc78b57d71ad01faaAndrew Rossignol if (!eventPosted) { 2697e2da194710e593ad1248d4fc78b57d71ad01faaAndrew Rossignol memoryFree(event); 2707e2da194710e593ad1248d4fc78b57d71ad01faaAndrew Rossignol } 27130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 27230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 27330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 27430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return eventPosted; 27530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 27630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 27730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::postScanMonitorAsyncResultEventFatal( 27830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 27930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 28030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!postScanMonitorAsyncResultEvent(nanoappInstanceId, success, enable, 28130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, cookie)) { 28230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan monitor async result event"); 28330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 28430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 28530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 28684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::postScanRequestAsyncResultEvent( 28784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 28884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 28984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool eventPosted = false; 29084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 29184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (event == nullptr) { 29284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate wifi scan request async result event"); 29384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 29484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN; 29584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->success = success; 29684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->errorCode = errorCode; 29784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->reserved = 0; 29884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->cookie = cookie; 29984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 30084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Post the event. 30150d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 30250d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .postEvent(CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback, 30350d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 30484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 30584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 30684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return eventPosted; 30784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 30884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 30984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::postScanRequestAsyncResultEventFatal( 31084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 31184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 31284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!postScanRequestAsyncResultEvent(nanoappInstanceId, success, errorCode, 31384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol cookie)) { 31484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan request async result event"); 31584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 31684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 31784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 318254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::postScanEventFatal(chreWifiScanEvent *event) { 31950d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol bool eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 32050d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .postEvent(CHRE_EVENT_WIFI_SCAN_RESULT, event, freeWifiScanEventCallback, 32150d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol kSystemInstanceId, kBroadcastInstanceId); 322254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!eventPosted) { 323254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol FATAL_ERROR("Failed to send WiFi scan event"); 324254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 325254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 326254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 32730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChangeSync(bool enabled, 32830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode) { 32930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Success is defined as having no errors ... in life ༼ つ ◕_◕ ༽つ 33030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = (errorCode == CHRE_ERROR_NONE); 33130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 33230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Always check the front of the queue. 33330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(!mScanMonitorStateTransitions.empty(), 33484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanMonitorStateChangeSync called with no transitions"); 33530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 33630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 33730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success &= (stateTransition.enable == enabled); 33830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 33930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 34030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 34130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 34230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 34330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 34430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol while (!mScanMonitorStateTransitions.empty()) { 34530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 34630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool hasScanMonitorRequest = nanoappHasScanMonitorRequest( 34730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.nanoappInstanceId); 34830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (scanMonitorIsInRequestedState( 34930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 35030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // We are already in the target state so just post an event indicating 35130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // success 35230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 35330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 35430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 35530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else if (scanMonitorStateTransitionIsRequired( 35630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 35730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (mPlatformWifi.configureScanMonitor(stateTransition.enable)) { 35830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 35930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 36030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 36130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol false /* success */, 36230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, CHRE_ERROR, 36330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.cookie); 36430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 36530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 36630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor state"); 36730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 36830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 36930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 37030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 37130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 37230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 37330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 37484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::handleScanResponseSync(bool pending, 37584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode) { 37684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT_LOG(mScanRequestingNanoappInstanceId.has_value(), 37784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanResponseSync called with no outstanding request"); 37884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (mScanRequestingNanoappInstanceId.has_value()) { 37984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = (pending && errorCode == CHRE_ERROR_NONE); 38084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol postScanRequestAsyncResultEventFatal(*mScanRequestingNanoappInstanceId, 38184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success, errorCode, 38284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie); 383254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 384254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // Set a flag to indicate that results may be pending. 385254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestResultsArePending = pending; 386254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 387254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (pending) { 38850d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 38950d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .findNanoappByInstanceId(*mScanRequestingNanoappInstanceId); 390254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 391254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Received WiFi scan response for unknown " 392254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "nanoapp"); 393254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 394254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->registerForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 395254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 396254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 39784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // If the scan results are not pending, clear the nanoapp instance ID. 39884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Otherwise, wait for the results to be delivered and then clear the 39984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // instance ID. 40084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId.reset(); 40184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 40284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 40384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 40484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 405254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::handleScanEventSync(chreWifiScanEvent *event) { 406254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (mScanRequestResultsArePending) { 407254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // Reset the event distribution logic once an entire scan event has been 408254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // received. 409254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanEventResultCountAccumulator += event->resultCount; 410254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (mScanEventResultCountAccumulator >= event->resultTotal) { 411254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanEventResultCountAccumulator = 0; 412254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestResultsArePending = false; 413254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 414254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 415254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 416254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol postScanEventFatal(event); 417254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 418254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 419254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent) { 420254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mPlatformWifi.releaseScanEvent(scanEvent); 421254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 422254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!mScanRequestResultsArePending 423254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol && mScanRequestingNanoappInstanceId.has_value()) { 42450d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 42550d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .findNanoappByInstanceId(*mScanRequestingNanoappInstanceId); 426254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 427254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Attempted to unsubscribe unknown nanoapp from " 428254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "WiFi scan events"); 429254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else if (!nanoappHasScanMonitorRequest(*mScanRequestingNanoappInstanceId)) { 430254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 431254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 432254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 433254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestingNanoappInstanceId.reset(); 434254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 435254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 436254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 437254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::freeWifiScanEventCallback(uint16_t eventType, 438254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol void *eventData) { 439254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData); 440254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 441254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol .handleFreeWifiScanEvent(scanEvent); 442254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 443254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 44456b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol} // namespace chre 445