wifi_request_manager.cc revision 71489dd53096ad835ae0aa4899a4c738041253a2
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" 237e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro#include "chre/util/system/debug_dump.h" 2456b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 2556b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignolnamespace chre { 2656b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 2730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew RossignolWifiRequestManager::WifiRequestManager() { 2830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Reserve space for at least one scan monitoring nanoapp. This ensures that 2930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // the first asynchronous push_back will succeed. Future push_backs will be 3030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // synchronous and failures will be returned to the client. 3130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorNanoapps.reserve(1)) { 3230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol FATAL_ERROR("Failed to allocate scan monitoring nanoapps list at startup"); 3330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 3430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 3530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 362ff52c6627054f8708e83eaccbcbd0db0af2899cBrian Duddievoid WifiRequestManager::init() { 372ff52c6627054f8708e83eaccbcbd0db0af2899cBrian Duddie mPlatformWifi.init(); 382ff52c6627054f8708e83eaccbcbd0db0af2899cBrian Duddie} 392ff52c6627054f8708e83eaccbcbd0db0af2899cBrian Duddie 40bdf404267034f69fc1555ef266d9dd12ba9215eeAndrew Rossignoluint32_t WifiRequestManager::getCapabilities() { 41bdf404267034f69fc1555ef266d9dd12ba9215eeAndrew Rossignol return mPlatformWifi.getCapabilities(); 4256b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol} 4356b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol 4430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::configureScanMonitor(Nanoapp *nanoapp, bool enable, 4530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 4630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT(nanoapp); 4730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 4830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = false; 4930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId = nanoapp->getInstanceId(); 50dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol bool hasScanMonitorRequest = nanoappHasScanMonitorRequest(instanceId); 5130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 5230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = addScanMonitorRequestToQueue(nanoapp, enable, cookie); 53dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol } else if (scanMonitorIsInRequestedState(enable, hasScanMonitorRequest)) { 5430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // The scan monitor is already in the requested state. A success event can 5530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // be posted immediately. 5630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = postScanMonitorAsyncResultEvent(instanceId, true /* success */, 5730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol enable, CHRE_ERROR_NONE, cookie); 58dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol } else if (scanMonitorStateTransitionIsRequired(enable, 59dfabf1a03bcf4184074fb2c397c17022c41acdbaAndrew Rossignol hasScanMonitorRequest)) { 6030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = addScanMonitorRequestToQueue(nanoapp, enable, cookie); 6130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (success) { 6230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = mPlatformWifi.configureScanMonitor(enable); 6330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 6430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // TODO: Add a pop_back method. 6530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.remove( 6630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.size() - 1); 6730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to enable the scan monitor for nanoapp instance %" PRIu32, 6830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol instanceId); 6930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 7030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 7130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 7230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor configuration"); 7330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 7430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 7530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 7630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 7730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 7884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::requestScan(Nanoapp *nanoapp, 7984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const chreWifiScanParams *params, 8084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 8184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT(nanoapp); 8284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 8384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = false; 8484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!mScanRequestingNanoappInstanceId.has_value()) { 8584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success = mPlatformWifi.requestScan(params); 8684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (success) { 8784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId = nanoapp->getInstanceId(); 8884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie = cookie; 8984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 9084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 9184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Active wifi scan request made while a request is in flight"); 9284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 9384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 9484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return success; 9584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 9684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 973a34ff2bf5e4afd466abb2b9af26abf719ec34fdAndrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChange(bool enabled, 983a34ff2bf5e4afd466abb2b9af26abf719ec34fdAndrew Rossignol uint8_t errorCode) { 9930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol struct CallbackState { 10030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enabled; 10130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode; 10230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol }; 10330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 104a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto *cbState = memoryAlloc<CallbackState>(); 105a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie if (cbState == nullptr) { 10630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate callback state for scan monitor state change"); 10730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 108a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->enabled = enabled; 109a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->errorCode = errorCode; 11030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 11196f33751ce98a3e64d90373a3a42f88458b3aef0Andrew Rossignol auto callback = [](uint16_t /* eventType */, void *eventData) { 11230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol auto *state = static_cast<CallbackState *>(eventData); 11330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 11430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol .handleScanMonitorStateChangeSync(state->enabled, state->errorCode); 11530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol memoryFree(state); 11630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol }; 11730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 11819b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol bool callbackDeferred = EventLoopManagerSingleton::get()->deferCallback( 119a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie SystemCallbackType::WifiScanMonitorStateChange, cbState, callback); 12019b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol if (!callbackDeferred) { 12119b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol memoryFree(cbState); 12219b9a23f49844d0334780be8eaf339d6065d2a36Andrew Rossignol } 12330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 124cbff0ad0e40b03ea9972e3446f1d238796e07398Andrew Rossignol} 125cbff0ad0e40b03ea9972e3446f1d238796e07398Andrew Rossignol 126d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanResponse(bool pending, 127d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol uint8_t errorCode) { 12884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol struct CallbackState { 12984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool pending; 13084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode; 13184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol }; 13284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 133a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie auto *cbState = memoryAlloc<CallbackState>(); 134a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie if (cbState == nullptr) { 13584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate callback state for wifi scan response"); 13684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 137a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->pending = pending; 138a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie cbState->errorCode = errorCode; 13984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 14096f33751ce98a3e64d90373a3a42f88458b3aef0Andrew Rossignol auto callback = [](uint16_t /* eventType */, void *eventData) { 14184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol auto *state = static_cast<CallbackState *>(eventData); 14284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 14384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol .handleScanResponseSync(state->pending, state->errorCode); 14484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol memoryFree(state); 14584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol }; 14684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 14784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 148a5b39579dd3fbd8d74d8efd8d6453fbb10490485Brian Duddie SystemCallbackType::WifiRequestScanResponse, cbState, callback); 14984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 150d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 151d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 152d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanEvent(chreWifiScanEvent *event) { 153254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol auto callback = [](uint16_t eventType, void *eventData) { 154254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData); 155254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 156254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol .handleScanEventSync(scanEvent); 157254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol }; 158254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 159254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->deferCallback( 160254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol SystemCallbackType::WifiHandleScanEvent, event, callback); 161d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 162d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 1637e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishigurobool WifiRequestManager::logStateToBuffer(char *buffer, size_t *bufferPos, 1647e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro size_t bufferSize) const { 1657e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro bool success = debugDumpPrint(buffer, bufferPos, bufferSize, "\nWifi: " 1667e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro "scan monitor %s\n", scanMonitorIsEnabled() ? 1677e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro "enabled" : "disabled"); 1687e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro 1697e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro success &= debugDumpPrint(buffer, bufferPos, bufferSize, 1707e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro " Wifi scan monitor enabled nanoapps:\n"); 1717e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro for (const auto& instanceId : mScanMonitorNanoapps) { 1727e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro success &= debugDumpPrint(buffer, bufferPos, bufferSize, 1737e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro " nanoappId=%" PRIu32 "\n", instanceId); 1747e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro } 1757e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro 1767e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro if (mScanRequestingNanoappInstanceId.has_value()) { 1777e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro success &= debugDumpPrint(buffer, bufferPos, bufferSize, 1787e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro " Wifi request pending nanoappId=%" PRIu32 "\n", 1797e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro mScanRequestingNanoappInstanceId.value()); 1807e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro } 1817e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro 1827e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro success &= debugDumpPrint(buffer, bufferPos, bufferSize, 1837e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro " Wifi transition queue:\n"); 1847e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro for (const auto& transition : mScanMonitorStateTransitions) { 1857e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro success &= debugDumpPrint(buffer, bufferPos, bufferSize, 1867e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro " enable=%s nanoappId=%" PRIu32 "\n", 1877e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro transition.enable ? "true" : "false", 1887e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro transition.nanoappInstanceId); 1897e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro } 1907e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro 1917e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro return success; 1927e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro} 1937e76ba4dbeea9ea33132bf31b7c3887284c4bd87Arthur Ishiguro 19430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsEnabled() const { 19530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return !mScanMonitorNanoapps.empty(); 19630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 19730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 19830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::nanoappHasScanMonitorRequest( 19930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId, size_t *nanoappIndex) const { 20030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol size_t index = mScanMonitorNanoapps.find(instanceId); 20144b56ef8ab3ef4de08f2fc84e469dfb3e84e8d08Andrew Rossignol bool hasScanMonitorRequest = (index != mScanMonitorNanoapps.size()); 20230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (hasScanMonitorRequest && nanoappIndex != nullptr) { 20330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol *nanoappIndex = index; 20430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 20530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 20630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return hasScanMonitorRequest; 20730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 20830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 20930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsInRequestedState( 21030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 21130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return (requestedState == scanMonitorIsEnabled() || (!requestedState 21230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && (!nanoappHasRequest || mScanMonitorNanoapps.size() > 1))); 21330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 21430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 21530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorStateTransitionIsRequired( 21630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 21730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return ((requestedState && mScanMonitorNanoapps.empty()) 21830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol || (!requestedState && nanoappHasRequest 21930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && mScanMonitorNanoapps.size() == 1)); 22030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 22130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 22230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::addScanMonitorRequestToQueue(Nanoapp *nanoapp, 22330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enable, 22430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 22530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol ScanMonitorStateTransition scanMonitorStateTransition; 22630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.nanoappInstanceId = nanoapp->getInstanceId(); 22730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.cookie = cookie; 22830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.enable = enable; 22930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 23030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = mScanMonitorStateTransitions.push(scanMonitorStateTransition); 23130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 23230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGW("Too many scan monitor state transitions"); 23330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 23430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 23530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 23630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 23730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 23830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::updateNanoappScanMonitoringList(bool enable, 23930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId) { 24030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = true; 24150d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 24250d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .findNanoappByInstanceId(instanceId); 243254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 244254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Failed to update scan monitoring list for " 245254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "non-existent nanoapp"); 24630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 247254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol size_t nanoappIndex; 248254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol bool hasExistingRequest = nanoappHasScanMonitorRequest(instanceId, 249254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol &nanoappIndex); 250254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (enable) { 251254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!hasExistingRequest) { 252254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = nanoapp->registerForBroadcastEvent( 253254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_EVENT_WIFI_SCAN_RESULT); 254254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!success) { 255254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Failed to register nanoapp for wifi scan events"); 256254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 257254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // The scan monitor was successfully enabled for this nanoapp and 258254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // there is no existing request. Add it to the list of scan monitoring 259254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // nanoapps. 260254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = mScanMonitorNanoapps.push_back(instanceId); 261254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!success) { 262254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 263254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Failed to add nanoapp to the list of scan monitoring " 264254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "nanoapps"); 265254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 266254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 267254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 26830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 269254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!hasExistingRequest) { 270254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol success = false; 271254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol LOGE("Received a scan monitor state change for a non-existent nanoapp"); 272254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 273254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // The scan monitor was successfully disabled for a previously enabled 274254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // nanoapp. Remove it from the list of scan monitoring nanoapps. 275254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanMonitorNanoapps.erase(nanoappIndex); 276254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 277254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 27830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 27930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 28030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 28130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 28230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 28330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 28430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::postScanMonitorAsyncResultEvent( 28530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 28630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 28730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Allocate and post an event to the nanoapp requesting wifi. 28830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool eventPosted = false; 28930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success || updateNanoappScanMonitoringList(enable, nanoappInstanceId)) { 29030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 29130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (event == nullptr) { 29230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate wifi scan monitor async result event"); 29330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 29430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR; 29530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->success = success; 29630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->errorCode = errorCode; 29730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->reserved = 0; 29830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->cookie = cookie; 29930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 30030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Post the event. 30150d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 30250d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .postEvent(CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback, 30350d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 3047e2da194710e593ad1248d4fc78b57d71ad01faaAndrew Rossignol if (!eventPosted) { 3057e2da194710e593ad1248d4fc78b57d71ad01faaAndrew Rossignol memoryFree(event); 3067e2da194710e593ad1248d4fc78b57d71ad01faaAndrew Rossignol } 30730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 30830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 30930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 31030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return eventPosted; 31130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 31230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 31330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::postScanMonitorAsyncResultEventFatal( 31430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 31530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 31630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!postScanMonitorAsyncResultEvent(nanoappInstanceId, success, enable, 31730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, cookie)) { 31830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan monitor async result event"); 31930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 32030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 32130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 32284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::postScanRequestAsyncResultEvent( 32384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 32484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 32584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool eventPosted = false; 32684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 32784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (event == nullptr) { 32884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate wifi scan request async result event"); 32984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 33084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN; 33184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->success = success; 33284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->errorCode = errorCode; 33384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->reserved = 0; 33484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->cookie = cookie; 33584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 33684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Post the event. 33750d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 33850d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .postEvent(CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback, 33950d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 34084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 34184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 34284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return eventPosted; 34384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 34484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 34584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::postScanRequestAsyncResultEventFatal( 34684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 34784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 34884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!postScanRequestAsyncResultEvent(nanoappInstanceId, success, errorCode, 34984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol cookie)) { 35084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan request async result event"); 35184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 35284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 35384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 354254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::postScanEventFatal(chreWifiScanEvent *event) { 35550d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol bool eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 35650d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .postEvent(CHRE_EVENT_WIFI_SCAN_RESULT, event, freeWifiScanEventCallback, 35750d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol kSystemInstanceId, kBroadcastInstanceId); 358254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!eventPosted) { 359254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol FATAL_ERROR("Failed to send WiFi scan event"); 360254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 361254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 362254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 36330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChangeSync(bool enabled, 36430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode) { 36530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Success is defined as having no errors ... in life ༼ つ ◕_◕ ༽つ 36630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = (errorCode == CHRE_ERROR_NONE); 36730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 3681c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie // TODO(b/62904616): re-enable this assertion 3691c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie //CHRE_ASSERT_LOG(!mScanMonitorStateTransitions.empty(), 3701c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie // "handleScanMonitorStateChangeSync called with no transitions"); 3711c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie if (mScanMonitorStateTransitions.empty()) { 3721c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie LOGE("WiFi PAL error: handleScanMonitorStateChangeSync called with no " 3731c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie "transitions (enabled %d errorCode %" PRIu8 ")", enabled, errorCode); 3741c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie } 3751c815825047c0a8974f4d59fd6120766eca672d0Brian Duddie 37630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Always check the front of the queue. 37730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 37830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 37930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success &= (stateTransition.enable == enabled); 38030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 38130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 38230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 38330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 38430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 38530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 38630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol while (!mScanMonitorStateTransitions.empty()) { 38730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 38830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool hasScanMonitorRequest = nanoappHasScanMonitorRequest( 38930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.nanoappInstanceId); 39030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (scanMonitorIsInRequestedState( 39130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 39230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // We are already in the target state so just post an event indicating 39330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // success 39430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 39530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 39630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 39730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else if (scanMonitorStateTransitionIsRequired( 39830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 39930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (mPlatformWifi.configureScanMonitor(stateTransition.enable)) { 40030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 40130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 40230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 40330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol false /* success */, 40430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, CHRE_ERROR, 40530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.cookie); 40630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 40730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 40830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor state"); 40930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 41030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 41130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 41230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 41330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 41430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 41530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 41684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::handleScanResponseSync(bool pending, 41784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode) { 41884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT_LOG(mScanRequestingNanoappInstanceId.has_value(), 41984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanResponseSync called with no outstanding request"); 42084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (mScanRequestingNanoappInstanceId.has_value()) { 42184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = (pending && errorCode == CHRE_ERROR_NONE); 42284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol postScanRequestAsyncResultEventFatal(*mScanRequestingNanoappInstanceId, 42384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success, errorCode, 42484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie); 425254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 426254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // Set a flag to indicate that results may be pending. 427254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestResultsArePending = pending; 428254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 429254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (pending) { 43050d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 43150d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .findNanoappByInstanceId(*mScanRequestingNanoappInstanceId); 432254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 433254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Received WiFi scan response for unknown " 434254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "nanoapp"); 435254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 436254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->registerForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 437254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 438254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else { 43984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // If the scan results are not pending, clear the nanoapp instance ID. 44084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Otherwise, wait for the results to be delivered and then clear the 44184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // instance ID. 44284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId.reset(); 44384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 44484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 44584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 44684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 447254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::handleScanEventSync(chreWifiScanEvent *event) { 44871489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignol postScanEventFatal(event); 44971489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignol} 45071489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignol 45171489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignolvoid WifiRequestManager::handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent) { 452254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (mScanRequestResultsArePending) { 453254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol // Reset the event distribution logic once an entire scan event has been 45471489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignol // received and processed by the nanoapp requesting the scan event. 45571489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignol mScanEventResultCountAccumulator += scanEvent->resultCount; 45671489dd53096ad835ae0aa4899a4c738041253a2Andrew Rossignol if (mScanEventResultCountAccumulator >= scanEvent->resultTotal) { 457254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanEventResultCountAccumulator = 0; 458254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestResultsArePending = false; 459254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 460254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 461254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 462254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mPlatformWifi.releaseScanEvent(scanEvent); 463254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 464254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (!mScanRequestResultsArePending 465254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol && mScanRequestingNanoappInstanceId.has_value()) { 46650d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 46750d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol .findNanoappByInstanceId(*mScanRequestingNanoappInstanceId); 468254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol if (nanoapp == nullptr) { 469254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol CHRE_ASSERT_LOG(false, "Attempted to unsubscribe unknown nanoapp from " 470254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol "WiFi scan events"); 471254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } else if (!nanoappHasScanMonitorRequest(*mScanRequestingNanoappInstanceId)) { 472254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT); 473254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 474254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 475254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol mScanRequestingNanoappInstanceId.reset(); 476254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol } 477254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 478254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 479254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignolvoid WifiRequestManager::freeWifiScanEventCallback(uint16_t eventType, 480254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol void *eventData) { 481254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData); 482254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol EventLoopManagerSingleton::get()->getWifiRequestManager() 483254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol .handleFreeWifiScanEvent(scanEvent); 484254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol} 485254795cf8e20f1187367924af8ae7967e6052f9bAndrew Rossignol 48656b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol} // namespace chre 487