123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- /*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <cinttypes>
- #include <cstddef>
- #include <cstring>
- #include "chre/core/event_loop_manager.h"
- #include "chre/core/wifi_request_manager.h"
- #include "chre/platform/fatal_error.h"
- #include "chre/platform/log.h"
- #include "chre/platform/system_time.h"
- #include "chre/util/system/debug_dump.h"
- #include "chre_api/chre/version.h"
- namespace chre {
- WifiRequestManager::WifiRequestManager() {
- // Reserve space for at least one scan monitoring nanoapp. This ensures that
- // the first asynchronous push_back will succeed. Future push_backs will be
- // synchronous and failures will be returned to the client.
- if (!mScanMonitorNanoapps.reserve(1)) {
- FATAL_ERROR_OOM();
- }
- }
- void WifiRequestManager::init() {
- mPlatformWifi.init();
- }
- uint32_t WifiRequestManager::getCapabilities() {
- return mPlatformWifi.getCapabilities();
- }
- bool WifiRequestManager::configureScanMonitor(Nanoapp *nanoapp, bool enable,
- const void *cookie) {
- CHRE_ASSERT(nanoapp);
- bool success = false;
- uint32_t instanceId = nanoapp->getInstanceId();
- bool hasScanMonitorRequest = nanoappHasScanMonitorRequest(instanceId);
- if (!mPendingScanMonitorRequests.empty()) {
- success = addScanMonitorRequestToQueue(nanoapp, enable, cookie);
- } else if (scanMonitorIsInRequestedState(enable, hasScanMonitorRequest)) {
- // The scan monitor is already in the requested state. A success event can
- // be posted immediately.
- success = postScanMonitorAsyncResultEvent(instanceId, true /* success */,
- enable, CHRE_ERROR_NONE, cookie);
- } else if (scanMonitorStateTransitionIsRequired(enable,
- hasScanMonitorRequest)) {
- success = addScanMonitorRequestToQueue(nanoapp, enable, cookie);
- if (success) {
- success = mPlatformWifi.configureScanMonitor(enable);
- if (!success) {
- mPendingScanMonitorRequests.pop_back();
- LOGE("Failed to enable the scan monitor for nanoapp instance %" PRIu32,
- instanceId);
- }
- }
- } else {
- CHRE_ASSERT_LOG(false, "Invalid scan monitor configuration");
- }
- return success;
- }
- bool WifiRequestManager::requestRanging(
- Nanoapp *nanoapp, const struct chreWifiRangingParams *params,
- const void *cookie) {
- CHRE_ASSERT(nanoapp);
- bool success = false;
- if (!mPendingRangingRequests.emplace()) {
- LOGE("Can't issue new RTT request; pending queue full");
- } else {
- PendingRangingRequest& req = mPendingRangingRequests.back();
- req.nanoappInstanceId = nanoapp->getInstanceId();
- req.cookie = cookie;
- if (mPendingRangingRequests.size() == 1) {
- // First in line; dispatch request immediately
- success = mPlatformWifi.requestRanging(params);
- if (!success) {
- LOGE("WiFi RTT request failed");
- mPendingRangingRequests.pop_back();
- } else {
- mRangingResponseTimeout = SystemTime::getMonotonicTime()
- + Nanoseconds(CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS);
- }
- } else {
- // Dispatch request later, after prior requests finish
- // TODO(b/65331248): use a timer to ensure the platform is meeting its
- // contract
- CHRE_ASSERT_LOG(SystemTime::getMonotonicTime() <= mRangingResponseTimeout,
- "WiFi platform didn't give callback in time");
- success = req.targetList.copy_array(params->targetList,
- params->targetListLen);
- if (!success) {
- LOG_OOM();
- mPendingRangingRequests.pop_back();
- }
- }
- }
- return success;
- }
- bool WifiRequestManager::requestScan(Nanoapp *nanoapp,
- const struct chreWifiScanParams *params,
- const void *cookie) {
- CHRE_ASSERT(nanoapp);
- // TODO(b/65331248): replace with a timer to actively check response timeout
- bool timedOut = (mScanRequestingNanoappInstanceId.has_value()
- && mLastScanRequestTime
- + Nanoseconds(CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS)
- < SystemTime::getMonotonicTime());
- if (timedOut) {
- LOGE("Scan request async response timed out");
- mScanRequestingNanoappInstanceId.reset();
- }
- // Handle compatibility with nanoapps compiled against API v1.1, which doesn't
- // include the radioChainPref parameter in chreWifiScanParams
- struct chreWifiScanParams paramsCompat;
- if (nanoapp->getTargetApiVersion() < CHRE_API_VERSION_1_2) {
- memcpy(¶msCompat, params, offsetof(chreWifiScanParams, radioChainPref));
- paramsCompat.radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT;
- params = ¶msCompat;
- }
- bool success = false;
- if (mScanRequestingNanoappInstanceId.has_value()) {
- LOGE("Active wifi scan request made while a request is in flight");
- } else {
- success = mPlatformWifi.requestScan(params);
- if (!success) {
- LOGE("Wifi scan request failed");
- } else {
- mScanRequestingNanoappInstanceId = nanoapp->getInstanceId();
- mScanRequestingNanoappCookie = cookie;
- mLastScanRequestTime = SystemTime::getMonotonicTime();
- }
- }
- return success;
- }
- void WifiRequestManager::handleScanMonitorStateChange(bool enabled,
- uint8_t errorCode) {
- struct CallbackState {
- bool enabled;
- uint8_t errorCode;
- };
- auto *cbState = memoryAlloc<CallbackState>();
- if (cbState == nullptr) {
- LOG_OOM();
- } else {
- cbState->enabled = enabled;
- cbState->errorCode = errorCode;
- auto callback = [](uint16_t /* eventType */, void *eventData) {
- auto *state = static_cast<CallbackState *>(eventData);
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .handleScanMonitorStateChangeSync(state->enabled, state->errorCode);
- memoryFree(state);
- };
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::WifiScanMonitorStateChange, cbState, callback);
- }
- }
- void WifiRequestManager::handleScanResponse(bool pending,
- uint8_t errorCode) {
- struct CallbackState {
- bool pending;
- uint8_t errorCode;
- };
- auto *cbState = memoryAlloc<CallbackState>();
- if (cbState == nullptr) {
- LOG_OOM();
- } else {
- cbState->pending = pending;
- cbState->errorCode = errorCode;
- auto callback = [](uint16_t /* eventType */, void *eventData) {
- auto *state = static_cast<CallbackState *>(eventData);
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .handleScanResponseSync(state->pending, state->errorCode);
- memoryFree(state);
- };
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::WifiRequestScanResponse, cbState, callback);
- }
- }
- void WifiRequestManager::handleRangingEvent(
- uint8_t errorCode, struct chreWifiRangingEvent *event) {
- // Use two different callbacks to avoid needing a temporary allocation to
- // carry the error code into the event loop context
- if (errorCode != CHRE_ERROR_NONE) {
- // Enables passing the error code through the event data pointer to avoid
- // allocating memory
- union NestedErrorCode {
- void *eventData;
- uint8_t errorCode;
- };
- auto errorCb = [](uint16_t /* eventType */, void *eventData) {
- NestedErrorCode cbErrorCode;
- cbErrorCode.eventData = eventData;
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .handleRangingEventSync(cbErrorCode.errorCode, nullptr);
- };
- NestedErrorCode error = {};
- error.errorCode = errorCode;
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::WifiHandleFailedRanging, error.eventData, errorCb);
- } else {
- auto successCb = [](uint16_t /* eventType */, void *eventData) {
- auto *rttEvent = static_cast<struct chreWifiRangingEvent *>(eventData);
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .handleRangingEventSync(CHRE_ERROR_NONE, rttEvent);
- };
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::WifiHandleRangingEvent, event, successCb);
- }
- }
- void WifiRequestManager::handleScanEvent(chreWifiScanEvent *event) {
- auto callback = [](uint16_t eventType, void *eventData) {
- chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData);
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .postScanEventFatal(scanEvent);
- };
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::WifiHandleScanEvent, event, callback);
- }
- void WifiRequestManager::logStateToBuffer(char *buffer, size_t *bufferPos,
- size_t bufferSize) const {
- debugDumpPrint(buffer, bufferPos, bufferSize,
- "\nWifi: scan monitor %s\n",
- scanMonitorIsEnabled() ? "enabled" : "disabled");
- debugDumpPrint(buffer, bufferPos, bufferSize,
- " Wifi scan monitor enabled nanoapps:\n");
- for (const auto& instanceId : mScanMonitorNanoapps) {
- debugDumpPrint(buffer, bufferPos, bufferSize,
- " nanoappId=%" PRIu32 "\n", instanceId);
- }
- if (mScanRequestingNanoappInstanceId.has_value()) {
- debugDumpPrint(buffer, bufferPos, bufferSize,
- " Wifi request pending nanoappId=%" PRIu32 "\n",
- mScanRequestingNanoappInstanceId.value());
- }
- debugDumpPrint(buffer, bufferPos, bufferSize,
- " Wifi transition queue:\n");
- for (const auto& transition : mPendingScanMonitorRequests) {
- debugDumpPrint(buffer, bufferPos, bufferSize,
- " enable=%s nanoappId=%" PRIu32 "\n",
- transition.enable ? "true" : "false",
- transition.nanoappInstanceId);
- }
- }
- bool WifiRequestManager::scanMonitorIsEnabled() const {
- return !mScanMonitorNanoapps.empty();
- }
- bool WifiRequestManager::nanoappHasScanMonitorRequest(
- uint32_t instanceId, size_t *nanoappIndex) const {
- size_t index = mScanMonitorNanoapps.find(instanceId);
- bool hasScanMonitorRequest = (index != mScanMonitorNanoapps.size());
- if (hasScanMonitorRequest && nanoappIndex != nullptr) {
- *nanoappIndex = index;
- }
- return hasScanMonitorRequest;
- }
- bool WifiRequestManager::scanMonitorIsInRequestedState(
- bool requestedState, bool nanoappHasRequest) const {
- return (requestedState == scanMonitorIsEnabled() || (!requestedState
- && (!nanoappHasRequest || mScanMonitorNanoapps.size() > 1)));
- }
- bool WifiRequestManager::scanMonitorStateTransitionIsRequired(
- bool requestedState, bool nanoappHasRequest) const {
- return ((requestedState && mScanMonitorNanoapps.empty())
- || (!requestedState && nanoappHasRequest
- && mScanMonitorNanoapps.size() == 1));
- }
- bool WifiRequestManager::addScanMonitorRequestToQueue(Nanoapp *nanoapp,
- bool enable,
- const void *cookie) {
- PendingScanMonitorRequest scanMonitorStateTransition;
- scanMonitorStateTransition.nanoappInstanceId = nanoapp->getInstanceId();
- scanMonitorStateTransition.cookie = cookie;
- scanMonitorStateTransition.enable = enable;
- bool success = mPendingScanMonitorRequests.push(scanMonitorStateTransition);
- if (!success) {
- LOGW("Too many scan monitor state transitions");
- }
- return success;
- }
- bool WifiRequestManager::updateNanoappScanMonitoringList(bool enable,
- uint32_t instanceId) {
- bool success = true;
- Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop()
- .findNanoappByInstanceId(instanceId);
- if (nanoapp == nullptr) {
- LOGW("Failed to update scan monitoring list for non-existent nanoapp");
- } else {
- size_t nanoappIndex;
- bool hasExistingRequest = nanoappHasScanMonitorRequest(instanceId,
- &nanoappIndex);
- if (enable) {
- if (!hasExistingRequest) {
- // The scan monitor was successfully enabled for this nanoapp and
- // there is no existing request. Add it to the list of scan monitoring
- // nanoapps.
- success = mScanMonitorNanoapps.push_back(instanceId);
- if (!success) {
- LOG_OOM();
- } else {
- nanoapp->registerForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT);
- }
- }
- } else if (hasExistingRequest) {
- // The scan monitor was successfully disabled for a previously enabled
- // nanoapp. Remove it from the list of scan monitoring nanoapps.
- mScanMonitorNanoapps.erase(nanoappIndex);
- nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT);
- } // else disabling an inactive request, treat as success per the CHRE API.
- }
- return success;
- }
- bool WifiRequestManager::postScanMonitorAsyncResultEvent(
- uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode,
- const void *cookie) {
- // Allocate and post an event to the nanoapp requesting wifi.
- bool eventPosted = false;
- if (!success || updateNanoappScanMonitoringList(enable, nanoappInstanceId)) {
- chreAsyncResult *event = memoryAlloc<chreAsyncResult>();
- if (event == nullptr) {
- LOG_OOM();
- } else {
- event->requestType = CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR;
- event->success = success;
- event->errorCode = errorCode;
- event->reserved = 0;
- event->cookie = cookie;
- // Post the event.
- eventPosted =
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback,
- nanoappInstanceId);
- if (!eventPosted) {
- memoryFree(event);
- }
- }
- }
- return eventPosted;
- }
- void WifiRequestManager::postScanMonitorAsyncResultEventFatal(
- uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode,
- const void *cookie) {
- if (!postScanMonitorAsyncResultEvent(nanoappInstanceId, success, enable,
- errorCode, cookie)) {
- FATAL_ERROR("Failed to send WiFi scan monitor async result event");
- }
- }
- bool WifiRequestManager::postScanRequestAsyncResultEvent(
- uint32_t nanoappInstanceId, bool success, uint8_t errorCode,
- const void *cookie) {
- bool eventPosted = false;
- chreAsyncResult *event = memoryAlloc<chreAsyncResult>();
- if (event == nullptr) {
- LOG_OOM();
- } else {
- event->requestType = CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN;
- event->success = success;
- event->errorCode = errorCode;
- event->reserved = 0;
- event->cookie = cookie;
- // Post the event.
- eventPosted =
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback,
- nanoappInstanceId);
- }
- return eventPosted;
- }
- void WifiRequestManager::postScanRequestAsyncResultEventFatal(
- uint32_t nanoappInstanceId, bool success, uint8_t errorCode,
- const void *cookie) {
- if (!postScanRequestAsyncResultEvent(nanoappInstanceId, success, errorCode,
- cookie)) {
- FATAL_ERROR("Failed to send WiFi scan request async result event");
- }
- }
- void WifiRequestManager::postScanEventFatal(chreWifiScanEvent *event) {
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- CHRE_EVENT_WIFI_SCAN_RESULT, event, freeWifiScanEventCallback);
- }
- void WifiRequestManager::handleScanMonitorStateChangeSync(bool enabled,
- uint8_t errorCode) {
- // Success is defined as having no errors ... in life ༼ つ ◕_◕ ༽つ
- bool success = (errorCode == CHRE_ERROR_NONE);
- // TODO(b/62904616): re-enable this assertion
- //CHRE_ASSERT_LOG(!mScanMonitorStateTransitions.empty(),
- // "handleScanMonitorStateChangeSync called with no transitions");
- if (mPendingScanMonitorRequests.empty()) {
- LOGE("WiFi PAL error: handleScanMonitorStateChangeSync called with no "
- "transitions (enabled %d errorCode %" PRIu8 ")", enabled, errorCode);
- }
- // Always check the front of the queue.
- if (!mPendingScanMonitorRequests.empty()) {
- const auto& stateTransition = mPendingScanMonitorRequests.front();
- success &= (stateTransition.enable == enabled);
- postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId,
- success, stateTransition.enable,
- errorCode, stateTransition.cookie);
- mPendingScanMonitorRequests.pop();
- }
- while (!mPendingScanMonitorRequests.empty()) {
- const auto& stateTransition = mPendingScanMonitorRequests.front();
- bool hasScanMonitorRequest = nanoappHasScanMonitorRequest(
- stateTransition.nanoappInstanceId);
- if (scanMonitorIsInRequestedState(
- stateTransition.enable, hasScanMonitorRequest)) {
- // We are already in the target state so just post an event indicating
- // success
- postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId,
- true /* success */,
- stateTransition.enable,
- CHRE_ERROR_NONE,
- stateTransition.cookie);
- } else if (scanMonitorStateTransitionIsRequired(
- stateTransition.enable, hasScanMonitorRequest)) {
- if (mPlatformWifi.configureScanMonitor(stateTransition.enable)) {
- break;
- } else {
- postScanMonitorAsyncResultEventFatal(stateTransition.nanoappInstanceId,
- false /* success */,
- stateTransition.enable, CHRE_ERROR,
- stateTransition.cookie);
- }
- } else {
- CHRE_ASSERT_LOG(false, "Invalid scan monitor state");
- break;
- }
- mPendingScanMonitorRequests.pop();
- }
- }
- void WifiRequestManager::handleScanResponseSync(bool pending,
- uint8_t errorCode) {
- // TODO(b/65206783): re-enable this assertion
- //CHRE_ASSERT_LOG(mScanRequestingNanoappInstanceId.has_value(),
- // "handleScanResponseSync called with no outstanding request");
- if (!mScanRequestingNanoappInstanceId.has_value()) {
- LOGE("handleScanResponseSync called with no outstanding request");
- }
- // TODO: raise this to CHRE_ASSERT_LOG
- if (!pending && errorCode == CHRE_ERROR_NONE) {
- LOGE("Invalid wifi scan response");
- errorCode = CHRE_ERROR;
- }
- if (mScanRequestingNanoappInstanceId.has_value()) {
- bool success = (pending && errorCode == CHRE_ERROR_NONE);
- if (!success) {
- LOGW("Wifi scan request failed: pending %d, errorCode %" PRIu8,
- pending, errorCode);
- }
- postScanRequestAsyncResultEventFatal(*mScanRequestingNanoappInstanceId,
- success, errorCode,
- mScanRequestingNanoappCookie);
- // Set a flag to indicate that results may be pending.
- mScanRequestResultsArePending = pending;
- if (pending) {
- Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop()
- .findNanoappByInstanceId(*mScanRequestingNanoappInstanceId);
- if (nanoapp == nullptr) {
- LOGW("Received WiFi scan response for unknown nanoapp");
- } else {
- nanoapp->registerForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT);
- }
- } else {
- // If the scan results are not pending, clear the nanoapp instance ID.
- // Otherwise, wait for the results to be delivered and then clear the
- // instance ID.
- mScanRequestingNanoappInstanceId.reset();
- }
- }
- }
- bool WifiRequestManager::postRangingAsyncResult(uint8_t errorCode) {
- bool eventPosted = false;
- if (mPendingRangingRequests.empty()) {
- LOGE("Unexpected ranging event callback");
- } else {
- auto *event = memoryAlloc<struct chreAsyncResult>();
- if (event == nullptr) {
- LOG_OOM();
- } else {
- const PendingRangingRequest& req = mPendingRangingRequests.front();
- event->requestType = CHRE_WIFI_REQUEST_TYPE_RANGING;
- event->success = (errorCode == CHRE_ERROR_NONE);
- event->errorCode = errorCode;
- event->reserved = 0;
- event->cookie = req.cookie;
- eventPosted =
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- CHRE_EVENT_WIFI_ASYNC_RESULT, event, freeEventDataCallback,
- req.nanoappInstanceId);
- if (!eventPosted) {
- memoryFree(event);
- }
- }
- }
- return eventPosted;
- }
- bool WifiRequestManager::dispatchQueuedRangingRequest() {
- const PendingRangingRequest& req = mPendingRangingRequests.front();
- struct chreWifiRangingParams params = {};
- params.targetListLen = static_cast<uint8_t>(req.targetList.size());
- params.targetList = req.targetList.data();
- bool success = mPlatformWifi.requestRanging(¶ms);
- if (!success) {
- LOGE("Failed to issue queued ranging result");
- postRangingAsyncResult(CHRE_ERROR);
- mPendingRangingRequests.pop();
- } else {
- mRangingResponseTimeout = SystemTime::getMonotonicTime()
- + Nanoseconds(CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS);
- }
- return success;
- }
- void WifiRequestManager::handleRangingEventSync(
- uint8_t errorCode, struct chreWifiRangingEvent *event) {
- if (postRangingAsyncResult(errorCode)) {
- if (errorCode != CHRE_ERROR_NONE) {
- LOGW("RTT ranging failed with error %d", errorCode);
- } else {
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- CHRE_EVENT_WIFI_RANGING_RESULT, event, freeWifiRangingEventCallback,
- mPendingRangingRequests.front().nanoappInstanceId);
- }
- mPendingRangingRequests.pop();
- }
- // If we have any pending requests, try issuing them to the platform until the
- // first one succeeds
- while (!mPendingRangingRequests.empty() && !dispatchQueuedRangingRequest());
- }
- void WifiRequestManager::handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent) {
- if (mScanRequestResultsArePending) {
- // Reset the event distribution logic once an entire scan event has been
- // received and processed by the nanoapp requesting the scan event.
- mScanEventResultCountAccumulator += scanEvent->resultCount;
- if (mScanEventResultCountAccumulator >= scanEvent->resultTotal) {
- mScanEventResultCountAccumulator = 0;
- mScanRequestResultsArePending = false;
- }
- if (!mScanRequestResultsArePending
- && mScanRequestingNanoappInstanceId.has_value()) {
- Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop()
- .findNanoappByInstanceId(*mScanRequestingNanoappInstanceId);
- if (nanoapp == nullptr) {
- LOGW("Attempted to unsubscribe unknown nanoapp from WiFi scan events");
- } else if (!nanoappHasScanMonitorRequest(
- *mScanRequestingNanoappInstanceId)) {
- nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WIFI_SCAN_RESULT);
- }
- mScanRequestingNanoappInstanceId.reset();
- }
- }
- mPlatformWifi.releaseScanEvent(scanEvent);
- }
- void WifiRequestManager::freeWifiScanEventCallback(uint16_t eventType,
- void *eventData) {
- chreWifiScanEvent *scanEvent = static_cast<chreWifiScanEvent *>(eventData);
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .handleFreeWifiScanEvent(scanEvent);
- }
- void WifiRequestManager::freeWifiRangingEventCallback(uint16_t eventType,
- void *eventData) {
- auto *event = static_cast<struct chreWifiRangingEvent *>(eventData);
- EventLoopManagerSingleton::get()->getWifiRequestManager()
- .mPlatformWifi.releaseRangingEvent(event);
- }
- } // namespace chre
|