wifi_request_manager.cc revision 84723e6849eb2d8e08557d57d787c5ab7ba01982
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 9730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol auto *state = memoryAlloc<CallbackState>(); 9830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (state == nullptr) { 9930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate callback state for scan monitor state change"); 10030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 10130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol state->enabled = enabled; 10230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol state->errorCode = errorCode; 10330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 10430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 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( 11230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol SystemCallbackType::WifiScanMonitorStateChange, state, 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 12384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol auto *state = memoryAlloc<CallbackState>(); 12484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (state == nullptr) { 12584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate callback state for wifi scan response"); 12684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 12784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol state->pending = pending; 12884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol state->errorCode = errorCode; 12984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 13084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 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( 13884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol SystemCallbackType::WifiRequestScanResponse, state, callback); 13984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 140d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 141d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 142d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignolvoid WifiRequestManager::handleScanEvent(chreWifiScanEvent *event) { 143d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol // TODO: Implement this. 144d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol} 145d74b2f8991a8dfae2e24ccb0cc84264c48731d55Andrew Rossignol 14630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsEnabled() const { 14730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return !mScanMonitorNanoapps.empty(); 14830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 14930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 15030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::nanoappHasScanMonitorRequest( 15130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId, size_t *nanoappIndex) const { 15230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol size_t index = mScanMonitorNanoapps.find(instanceId); 15330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool hasScanMonitorRequest = (index == mScanMonitorNanoapps.size()); 15430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (hasScanMonitorRequest && nanoappIndex != nullptr) { 15530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol *nanoappIndex = index; 15630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 15730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 15830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return hasScanMonitorRequest; 15930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 16030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 16130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorIsInRequestedState( 16230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 16330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return (requestedState == scanMonitorIsEnabled() || (!requestedState 16430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && (!nanoappHasRequest || mScanMonitorNanoapps.size() > 1))); 16530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 16630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 16730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::scanMonitorStateTransitionIsRequired( 16830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool requestedState, bool nanoappHasRequest) const { 16930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return ((requestedState && mScanMonitorNanoapps.empty()) 17030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol || (!requestedState && nanoappHasRequest 17130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol && mScanMonitorNanoapps.size() == 1)); 17230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 17330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 17430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::addScanMonitorRequestToQueue(Nanoapp *nanoapp, 17530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool enable, 17630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 17730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol ScanMonitorStateTransition scanMonitorStateTransition; 17830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.nanoappInstanceId = nanoapp->getInstanceId(); 17930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.cookie = cookie; 18030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol scanMonitorStateTransition.enable = enable; 18130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 18230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = mScanMonitorStateTransitions.push(scanMonitorStateTransition); 18330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 18430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGW("Too many scan monitor state transitions"); 18530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 18630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 18730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 18830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 18930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 19030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::updateNanoappScanMonitoringList(bool enable, 19130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t instanceId) { 19230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = true; 19330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol size_t nanoappIndex; 19430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool hasExistingRequest = nanoappHasScanMonitorRequest(instanceId, 19530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol &nanoappIndex); 19630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (enable) { 19730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!hasExistingRequest) { 19830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // The scan monitor was successfully enabled for this nanoapp and there 19930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // is no existing request. Add it to the list of scan monitoring 20030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // nanoapps. 20130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = mScanMonitorNanoapps.push_back(instanceId); 20230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success) { 20330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to add nanoapp to the list of scan monitoring nanoapps"); 20430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 20530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 20630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 20730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!hasExistingRequest) { 20830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success = false; 20930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Received a scan monitor state change for a non-existent nanoapp"); 21030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 21130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // The scan monitor was successfully disabled for a previously enabled 21230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // nanoapp. Remove it from the list of scan monitoring nanoapps. 21330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorNanoapps.erase(nanoappIndex); 21430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 21530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 21630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 21730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return success; 21830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 21930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 22030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolbool WifiRequestManager::postScanMonitorAsyncResultEvent( 22130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 22230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 22330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Allocate and post an event to the nanoapp requesting wifi. 22430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool eventPosted = false; 22530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!success || updateNanoappScanMonitoringList(enable, nanoappInstanceId)) { 22630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 22730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (event == nullptr) { 22830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol LOGE("Failed to allocate wifi scan monitor async result event"); 22930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 23030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR; 23130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->success = success; 23230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->errorCode = errorCode; 23330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->reserved = 0; 23430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol event->cookie = cookie; 23530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 23630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Post the event. 23730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->postEvent( 23830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeWifiAsyncResultCallback, 23930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 24030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 24130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 24230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 24330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol return eventPosted; 24430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 24530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 24630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::postScanMonitorAsyncResultEventFatal( 24730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode, 24830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const void *cookie) { 24930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!postScanMonitorAsyncResultEvent(nanoappInstanceId, success, enable, 25030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, cookie)) { 25130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan monitor async result event"); 25230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 25330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 25430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 25584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolbool WifiRequestManager::postScanRequestAsyncResultEvent( 25684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 25784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 25884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool eventPosted = false; 25984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol chreAsyncResult *event = memoryAlloc<chreAsyncResult>(); 26084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (event == nullptr) { 26184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol LOGE("Failed to allocate wifi scan request async result event"); 26284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } else { 26384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->requestType = CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN; 26484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->success = success; 26584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->errorCode = errorCode; 26684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->reserved = 0; 26784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol event->cookie = cookie; 26884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 26984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Post the event. 27084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol eventPosted = EventLoopManagerSingleton::get()->postEvent( 27184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeWifiAsyncResultCallback, 27284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol kSystemInstanceId, nanoappInstanceId); 27384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 27484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 27584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol return eventPosted; 27684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 27784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 27884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::postScanRequestAsyncResultEventFatal( 27984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint32_t nanoappInstanceId, bool success, uint8_t errorCode, 28084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol const void *cookie) { 28184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!postScanRequestAsyncResultEvent(nanoappInstanceId, success, errorCode, 28284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol cookie)) { 28384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol FATAL_ERROR("Failed to send WiFi scan request async result event"); 28484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 28584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 28684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 28730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::handleScanMonitorStateChangeSync(bool enabled, 28830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol uint8_t errorCode) { 28930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Success is defined as having no errors ... in life ༼ つ ◕_◕ ༽つ 29030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool success = (errorCode == CHRE_ERROR_NONE); 29130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 29230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // Always check the front of the queue. 29330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(!mScanMonitorStateTransitions.empty(), 29484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanMonitorStateChangeSync called with no transitions"); 29530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (!mScanMonitorStateTransitions.empty()) { 29630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 29730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success &= (stateTransition.enable == enabled); 29830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 29930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 30030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 30130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 30230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 30330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 30430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol while (!mScanMonitorStateTransitions.empty()) { 30530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol const auto& stateTransition = mScanMonitorStateTransitions.front(); 30630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol bool hasScanMonitorRequest = nanoappHasScanMonitorRequest( 30730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.nanoappInstanceId); 30830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (scanMonitorIsInRequestedState( 30930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 31030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // We are already in the target state so just post an event indicating 31130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol // success 31230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 31330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol success, stateTransition.enable, 31430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol errorCode, stateTransition.cookie); 31530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else if (scanMonitorStateTransitionIsRequired( 31630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, hasScanMonitorRequest)) { 31730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol if (mPlatformWifi.configureScanMonitor(stateTransition.enable)) { 31830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 31930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 32030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId, 32130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol false /* success */, 32230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.enable, CHRE_ERROR, 32330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol stateTransition.cookie); 32430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 32530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } else { 32630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol CHRE_ASSERT_LOG(false, "Invalid scan monitor state"); 32730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol break; 32830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 32930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 33030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol mScanMonitorStateTransitions.pop(); 33130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol } 33230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 33330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 33484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignolvoid WifiRequestManager::handleScanResponseSync(bool pending, 33584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol uint8_t errorCode) { 33684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol CHRE_ASSERT_LOG(mScanRequestingNanoappInstanceId.has_value(), 33784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol "handleScanResponseSync called with no outstanding request"); 33884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (mScanRequestingNanoappInstanceId.has_value()) { 33984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol bool success = (pending && errorCode == CHRE_ERROR_NONE); 34084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol postScanRequestAsyncResultEventFatal(*mScanRequestingNanoappInstanceId, 34184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol success, errorCode, 34284723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappCookie); 34384723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol if (!pending) { 34484723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // If the scan results are not pending, clear the nanoapp instance ID. 34584723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // Otherwise, wait for the results to be delivered and then clear the 34684723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol // instance ID. 34784723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol mScanRequestingNanoappInstanceId.reset(); 34884723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 34984723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol } 35084723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol} 35184723e6849eb2d8e08557d57d787c5ab7ba01982Andrew Rossignol 35230f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignolvoid WifiRequestManager::freeWifiAsyncResultCallback(uint16_t eventType, 35330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol void *eventData) { 35430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol memoryFree(eventData); 35530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol} 35630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol 35756b7c22b1e7405d8075b6c8e4985f5d17e981d53Andrew Rossignol} // namespace chre 358