wifi_request_manager.cc revision 254795cf8e20f1187367924af8ae7967e6052f9b
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(); 4530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 4630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = addScanMonitorRequestToQueue(nanoapp, enable, cookie); 4730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else if (scanMonitorIsInRequestedState(enable, instanceId)) { 4830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // The scan monitor is already in the requested state. A success event can 4930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // be posted immediately. 5030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = postScanMonitorAsyncResultEvent(instanceId, true /* success */, 5130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol enable, CHRE_ERROR_NONE, cookie); 5230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else if (scanMonitorStateTransitionIsRequired(enable, instanceId)) { 5330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = addScanMonitorRequestToQueue(nanoapp, enable, cookie); 5430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (success) { 5530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = mPlatformWifi.configureScanMonitor(enable); 5630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 5730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // TODO: Add a pop_back method. 5830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.remove( 5930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.size() - 1); 6030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to enable the scan monitor for nanoapp instance %" PRIu32, 6130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol instanceId); 6230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 6330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 6430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 6530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor configuration"); 6630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 6730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 6830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 6930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 7030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 7184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::requestScan(Nanoapp *nanoapp, 7284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const chreWifiScanParams *params, 7384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 7484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT(nanoapp); 7584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 7684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = false; 7784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!mScanRequestingNanoappInstanceId.has_value()) { 7884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success = mPlatformWifi.requestScan(params); 7984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (success) { 8084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId = nanoapp->getInstanceId(); 8184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie = cookie; 8284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 8384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 8484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Active wifi scan request made while a request is in flight"); 8584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 8684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 8784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return success; 8884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 8984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 903a34ff2bf5e4afd466abb2b9af26abf719ec34fdAndrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChange(bool enabled, 913a34ff2bf5e4afd466abb2b9af26abf719ec34fdAndrew Rossignol uint8_t errorCode) { 9230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol struct CallbackState { 9330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enabled; 9430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode; 9530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol }; 9630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 97a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto *cbState = memoryAlloc<CallbackState>(); 98a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie if (cbState == nullptr) { 9930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate callback state for scan monitor state change"); 10030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 101a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->enabled = enabled; 102a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->errorCode = errorCode; 10330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 104a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto callback = [](uint16_t /*eventType*/, void *eventData) { 10530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol auto *state = static_cast<CallbackState *>(eventData); 10630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 10730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol .handleScanMonitorStateChangeSync(state->enabled, state->errorCode); 10830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol memoryFree(state); 10930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol }; 11030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 11130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 112a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie SystemCallbackType::WifiScanMonitorStateChange, cbState, callback); 11330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 114cbff0ad0e40b03ea9972e3446f1d238796e07398Andrew Rossignol} 115cbff0ad0e40b03ea9972e3446f1d238796e07398Andrew Rossignol 116d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanResponse(bool pending, 117d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol uint8_t errorCode) { 11884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol struct CallbackState { 11984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool pending; 12084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode; 12184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol }; 12284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 123a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto *cbState = memoryAlloc<CallbackState>(); 124a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie if (cbState == nullptr) { 12584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate callback state for wifi scan response"); 12684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 127a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->pending = pending; 128a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->errorCode = errorCode; 12984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 130a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto callback = [](uint16_t /*eventType*/, void *eventData) { 13184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol auto *state = static_cast<CallbackState *>(eventData); 13284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 13384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol .handleScanResponseSync(state->pending, state->errorCode); 13484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol memoryFree(state); 13584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol }; 13684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 13784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 138a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie SystemCallbackType::WifiRequestScanResponse, cbState, callback); 13984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 140d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 141d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 142d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanEvent(chreWifiScanEvent *event) { 143254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol auto callback = [](uint16_t eventType, void *eventData) { 144254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData); 145254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 146254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol .handleScanEventSync(scanEvent); 147254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol }; 148254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 149254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 150254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol SystemCallbackType::WifiHandleScanEvent, event, callback); 151d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 152d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 15330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsEnabled() const { 15430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return !mScanMonitorNanoapps.empty(); 15530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 15630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 15730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::nanoappHasScanMonitorRequest( 15830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId, size_t *nanoappIndex) const { 15930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol size_t index = mScanMonitorNanoapps.find(instanceId); 16044b56ef8ab3ef4de08f2fc84e469dfb3e84e8d08Andrew Rossignol bool hasScanMonitorRequest = (index != mScanMonitorNanoapps.size()); 16130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (hasScanMonitorRequest && nanoappIndex != nullptr) { 16230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol *nanoappIndex = index; 16330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 16430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 16530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return hasScanMonitorRequest; 16630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 16730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 16830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsInRequestedState( 16930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 17030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return (requestedState == scanMonitorIsEnabled() || (!requestedState 17130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && (!nanoappHasRequest || mScanMonitorNanoapps.size() > 1))); 17230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 17330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 17430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorStateTransitionIsRequired( 17530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 17630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return ((requestedState && mScanMonitorNanoapps.empty()) 17730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol || (!requestedState && nanoappHasRequest 17830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && mScanMonitorNanoapps.size() == 1)); 17930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 18030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 18130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::addScanMonitorRequestToQueue(Nanoapp *nanoapp, 18230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enable, 18330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 18430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol ScanMonitorStateTransition scanMonitorStateTransition; 18530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.nanoappInstanceId = nanoapp->getInstanceId(); 18630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.cookie = cookie; 18730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.enable = enable; 18830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 18930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = mScanMonitorStateTransitions.push(scanMonitorStateTransition); 19030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 19130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGW("Too many scan monitor state transitions"); 19230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 19330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 19430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 19530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 19630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 19730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::updateNanoappScanMonitoringList(bool enable, 19830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId) { 19930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = true; 200254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()-> 201254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol findNanoappByInstanceId(instanceId); 202254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 203254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Failed to update scan monitoring list for " 204254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "non-existent nanoapp"); 20530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 206254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol size_t nanoappIndex; 207254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol bool hasExistingRequest = nanoappHasScanMonitorRequest(instanceId, 208254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol &nanoappIndex); 209254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (enable) { 210254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!hasExistingRequest) { 211254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = nanoapp->registerForBroadcastEvent( 212254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_EVENT_WIFI_SCAN_RESULT); 213254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!success) { 214254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Failed to register nanoapp for wifi scan events"); 215254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 216254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // The scan monitor was successfully enabled for this nanoapp and 217254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // there is no existing request. Add it to the list of scan monitoring 218254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // nanoapps. 219254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = mScanMonitorNanoapps.push_back(instanceId); 220254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!success) { 221254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 222254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Failed to add nanoapp to the list of scan monitoring " 223254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "nanoapps"); 224254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 225254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 226254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 22730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 228254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!hasExistingRequest) { 229254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = false; 230254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Received a scan monitor state change for a non-existent nanoapp"); 231254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 232254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // The scan monitor was successfully disabled for a previously enabled 233254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // nanoapp. Remove it from the list of scan monitoring nanoapps. 234254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanMonitorNanoapps.erase(nanoappIndex); 235254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 236254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 23730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 23830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 23930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 24030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 24130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 24230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 24330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::postScanMonitorAsyncResultEvent( 24430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 24530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 24630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Allocate and post an event to the nanoapp requesting wifi. 24730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool eventPosted = false; 24830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success || updateNanoappScanMonitoringList(enable, nanoappInstanceId)) { 24930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 25030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (event == nullptr) { 25130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate wifi scan monitor async result event"); 25230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 25330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR; 25430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->success = success; 25530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->errorCode = errorCode; 25630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->reserved = 0; 25730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->cookie = cookie; 25830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 25930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Post the event. 26030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->postEvent( 26130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeWifiAsyncResultCallback, 26230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 26330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 26430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 26530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 26630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return eventPosted; 26730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 26830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 26930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::postScanMonitorAsyncResultEventFatal( 27030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 27130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 27230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!postScanMonitorAsyncResultEvent(nanoappInstanceId, success, enable, 27330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, cookie)) { 27430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan monitor async result event"); 27530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 27630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 27730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 27884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::postScanRequestAsyncResultEvent( 27984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 28084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 28184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool eventPosted = false; 28284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 28384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (event == nullptr) { 28484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate wifi scan request async result event"); 28584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 28684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN; 28784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->success = success; 28884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->errorCode = errorCode; 28984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->reserved = 0; 29084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->cookie = cookie; 29184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 29284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Post the event. 29384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->postEvent( 29484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeWifiAsyncResultCallback, 29584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 29684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 29784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 29884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return eventPosted; 29984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 30084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 30184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::postScanRequestAsyncResultEventFatal( 30284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 30384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 30484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!postScanRequestAsyncResultEvent(nanoappInstanceId, success, errorCode, 30584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol cookie)) { 30684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan request async result event"); 30784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 30884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 30984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 310254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::postScanEventFatal(chreWifiScanEvent *event) { 311254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol bool eventPosted = EventLoopManagerSingleton::get()->postEvent( 312254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_EVENT_WIFI_SCAN_RESULT, event, freeWifiScanEventCallback, 313254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol kSystemInstanceId, kBroadcastInstanceId); 314254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!eventPosted) { 315254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol FATAL_ERROR("Failed to send WiFi scan event"); 316254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 317254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 318254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 31930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChangeSync(bool enabled, 32030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode) { 32130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Success is defined as having no errors ... in life ༼ つ ◕_◕ ༽つ 32230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = (errorCode == CHRE_ERROR_NONE); 32330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 32430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Always check the front of the queue. 32530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(!mScanMonitorStateTransitions.empty(), 32684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanMonitorStateChangeSync called with no transitions"); 32730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 32830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 32930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success &= (stateTransition.enable == enabled); 33030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 33130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 33230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 33330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 33430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 33530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 33630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol while (!mScanMonitorStateTransitions.empty()) { 33730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 33830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool hasScanMonitorRequest = nanoappHasScanMonitorRequest( 33930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.nanoappInstanceId); 34030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (scanMonitorIsInRequestedState( 34130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 34230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // We are already in the target state so just post an event indicating 34330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // success 34430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 34530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 34630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 34730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else if (scanMonitorStateTransitionIsRequired( 34830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 34930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (mPlatformWifi.configureScanMonitor(stateTransition.enable)) { 35030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 35130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 35230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 35330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol false /* success */, 35430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, CHRE_ERROR, 35530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.cookie); 35630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 35730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 35830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor state"); 35930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 36030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 36130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 36230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 36330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 36430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 36530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 36684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::handleScanResponseSync(bool pending, 36784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode) { 36884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT_LOG(mScanRequestingNanoappInstanceId.has_value(), 36984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanResponseSync called with no outstanding request"); 37084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (mScanRequestingNanoappInstanceId.has_value()) { 37184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = (pending && errorCode == CHRE_ERROR_NONE); 37284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol postScanRequestAsyncResultEventFatal(*mScanRequestingNanoappInstanceId, 37384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success, errorCode, 37484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie); 375254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 376254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // Set a flag to indicate that results may be pending. 377254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestResultsArePending = pending; 378254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 379254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (pending) { 380254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()-> 381254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol findNanoappByInstanceId(*mScanRequestingNanoappInstanceId); 382254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 383254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Received WiFi scan response for unknown " 384254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "nanoapp"); 385254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 386254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->registerForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 387254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 388254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 38984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // If the scan results are not pending, clear the nanoapp instance ID. 39084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Otherwise, wait for the results to be delivered and then clear the 39184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // instance ID. 39284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId.reset(); 39384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 39484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 39584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 39684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 397254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::handleScanEventSync(chreWifiScanEvent *event) { 398254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (mScanRequestResultsArePending) { 399254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // Reset the event distribution logic once an entire scan event has been 400254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // received. 401254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanEventResultCountAccumulator += event->resultCount; 402254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (mScanEventResultCountAccumulator >= event->resultTotal) { 403254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanEventResultCountAccumulator = 0; 404254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestResultsArePending = false; 405254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 406254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 407254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 408254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol postScanEventFatal(event); 409254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 410254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 411254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent) { 412254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mPlatformWifi.releaseScanEvent(scanEvent); 413254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 414254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!mScanRequestResultsArePending 415254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol && mScanRequestingNanoappInstanceId.has_value()) { 416254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()-> 417254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol findNanoappByInstanceId(*mScanRequestingNanoappInstanceId); 418254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 419254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Attempted to unsubscribe unknown nanoapp from " 420254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "WiFi scan events"); 421254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else if (!nanoappHasScanMonitorRequest(*mScanRequestingNanoappInstanceId)) { 422254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 423254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 424254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 425254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestingNanoappInstanceId.reset(); 426254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 427254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 428254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 42930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::freeWifiAsyncResultCallback(uint16_t eventType, 43030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol void *eventData) { 43130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol memoryFree(eventData); 43230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 43330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 434254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::freeWifiScanEventCallback(uint16_t eventType, 435254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol void *eventData) { 436254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData); 437254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 438254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol .handleFreeWifiScanEvent(scanEvent); 439254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 440254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 44156b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol} // namespace chre 442