blob: e38bea2c2d07fe50c77cc0e377d6bb3d68b0cb7c [file] [log] [blame]
/*
* 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.
*/
#ifndef CHRE_CORE_WIFI_REQUEST_MANAGER_H_
#define CHRE_CORE_WIFI_REQUEST_MANAGER_H_
#include "chre/core/nanoapp.h"
#include "chre/platform/platform_wifi.h"
#include "chre/util/non_copyable.h"
namespace chre {
/**
* The WifiRequestManager handles requests from nanoapps for Wifi information.
* This includes multiplexing multiple requests into one for the platform to
* handle.
*
* This class is effectively a singleton as there can only be one instance of
* the PlatformWifi instance.
*/
class WifiRequestManager : public NonCopyable {
public:
/**
* Initializes the WifiRequestManager with a default state and memory for any
* requests.
*/
WifiRequestManager();
/**
* @return the WiFi capabilities exposed by this platform.
*/
uint32_t getCapabilities();
/**
* Handles a request from a nanoapp to configure the scan monitor. This
* includes merging multiple requests for scan monitoring to the PAL (ie: if
* multiple apps enable the scan monitor the PAL is only enabled once).
*
* @param nanoapp The nanoapp that has requested that the scan monitor be
* configured.
* @param enable true to enable scan monitoring, false to disable scan
* monitoring.
* @param cookie A cookie that is round-tripped back to the nanoapp to
* provide a context when making the request.
* @return true if the request was accepted. The result is delivered
* asynchronously through a CHRE event.
*/
bool configureScanMonitor(Nanoapp *nanoapp, bool enable, const void *cookie);
/**
* Performs an active wifi scan.
*
* This is currently a 1:1 mapping into the PAL. If more than one nanoapp
* requests an active wifi scan, this will be an assertion failure for debug
* builds and a no-op in production (ie: subsequent requests are ignored).
*
* @param nanoapp The nanoapp that has requested an active wifi scan.
* @param params The parameters of the wifi scan.
* @param cookie A cookie that is round-tripped back to the nanoapp to provide
* a context when making the request.
* @return true if the request was accepted. The result is delivered
* asynchronously through a CHRE event.
*/
bool requestScan(Nanoapp *nanoapp, const chreWifiScanParams *params,
const void *cookie);
/**
* Handles the result of a request to PlatformWifi to change the state of the
* scan monitor.
*
* @param enabled true if the result of the operation was an enabled scan
* monitor.
* @param errorCode an error code that is provided to indicate success or what
* type of error has occurred. See the chreError enum in the CHRE API
* for additional details.
*/
void handleScanMonitorStateChange(bool enabled, uint8_t errorCode);
/**
* Handles the result of a request to the PlatformWifi to request an active
* Wifi scan.
*
* @param pending The result of the request was successful and the results
* be sent via the handleScanEvent method.
* @param errorCode an error code that is used to indicate success or what
* type of error has occurred. See the chreError enum in the CHRE API
* for additional details.
*/
void handleScanResponse(bool pending, uint8_t errorCode);
/**
* Handles a CHRE wifi scan event.
*
* @param event The wifi scan event provided to the wifi request manager. This
* memory is guaranteed not to be modified until it has been explicitly
* released through the PlatformWifi instance.
*/
void handleScanEvent(chreWifiScanEvent *event);
private:
/**
* Tracks the state of the wifi scan monitor.
*/
struct ScanMonitorStateTransition {
//! The nanoapp instance ID that prompted the change.
uint32_t nanoappInstanceId;
//! The cookie provided to the CHRE API when the nanoapp requested a change
//! of state to the scan monitoring.
const void *cookie;
//! The target state of the PAL scan monitor.
bool enable;
};
//! The maximum number of scan monitor state transitions that can be queued.
static constexpr size_t kMaxScanMonitorStateTransitions = 8;
//! The instance of the platform wifi interface.
PlatformWifi mPlatformWifi;
//! The queue of state transition requests for the scan monitor. Only one
//! asynchronous scan monitor state transition can be in flight at one time.
//! Any further requests are queued here.
ArrayQueue<ScanMonitorStateTransition,
kMaxScanMonitorStateTransitions> mScanMonitorStateTransitions;
//! The list of nanoapps who have enabled scan monitoring. This list is
//! maintained to ensure that nanoapps are always subscribed to wifi scan
//! results as requested. Note that a request for wifi scan monitoring can
//! exceed the duration of a single active wifi scan request. This makes it
//! insuitable only subscribe to wifi scan events when an active request is
//! made and the scan monitor must remain enabled when an active request has
//! completed.
DynamicVector<uint32_t> mScanMonitorNanoapps;
// TODO: Support multiple requests for active wifi scans.
//! The instance ID of the nanoapp that has a pending active scan request. At
//! this time, only one nanoapp can have a pending request for an active WiFi
//! scan.
Optional<uint32_t> mScanRequestingNanoappInstanceId;
//! The cookie passed in by a nanoapp making an active request for wifi scans.
//! Note that this will only be valid if the mScanRequestingNanoappInstanceId
//! is set.
const void *mScanRequestingNanoappCookie;
//! This is set to true if the results of an active scan request are pending.
bool mScanRequestResultsArePending = false;
//! Accumulates the number of scan event results to determine when the last
//! in a scan event stream has been received.
uint8_t mScanEventResultCountAccumulator = 0;
/**
* @return true if the scan monitor is enabled by any nanoapps.
*/
bool scanMonitorIsEnabled() const;
/**
* @param instanceId the instance ID of the nanoapp.
* @param index an optional pointer to a size_t to populate with the index of
* the nanoapp in the list of nanoapps.
* @return true if the nanoapp has an active request for scan monitoring.
*/
bool nanoappHasScanMonitorRequest(uint32_t instanceId,
size_t *index = nullptr) const;
/**
* @param requestedState The requested state to compare against.
* @param nanoappHasRequest The requesting nanoapp has an existing request.
* @return true if the scan monitor is in the requested state.
*/
bool scanMonitorIsInRequestedState(bool requestedState,
bool nanoappHasRequest) const;
/**
* @param requestedState The requested state to compare against.
* @param nanoappHasRequest The requesting nanoapp has an existing request.
* @return true if a state transition is required to reach the requested
* state.
*/
bool scanMonitorStateTransitionIsRequired(bool requestedState,
bool nanoappHasRequest) const;
/**
* Builds a scan monitor state transition and adds it to the queue of incoming
* requests.
* @param nanoapp A non-null pointer to a nanoapp that is requesting the
* change.
* @param enable The target requested scan monitoring state.
* @param cookie The pointer cookie passed in by the calling nanoapp to return
* to the nanoapp when the request completes.
* @return true if the request is enqueued or false if the queue is full.
*/
bool addScanMonitorRequestToQueue(Nanoapp *nanoapp, bool enable,
const void *cookie);
/**
* Adds a nanoapp to the list of nanoapps that are monitoring for wifi scans.
* @param enable true if enabling scan monitoring.
* @param instanceId The instance ID of the scan monitoring nanoapp.
* @return true if the nanoapp was added to the list.
*/
bool updateNanoappScanMonitoringList(bool enable, uint32_t instanceId);
/**
* Posts an event to a nanoapp indicating the result of a wifi scan monitoring
* configuration change.
*
* @param nanoappInstanceId The nanoapp instance ID to direct the event to.
* @param success If the request for a wifi resource was successful.
* @param enable The target state of the request. If enable is set to false
* and the request was successful, the nanoapp is removed from the
* list of nanoapps requesting scan monitoring.
* @param errorCode The error code when success is set to false.
* @param cookie The cookie to be provided to the nanoapp. This is
* round-tripped from the nanoapp to provide context.
* @return true if the event was successfully posted to the event loop.
*/
bool postScanMonitorAsyncResultEvent(
uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode,
const void *cookie);
/**
* Calls through to postScanMonitorAsyncResultEvent but invokes the
* FATAL_ERROR macro if the event is not posted successfully. This is used in
* asynchronous contexts where a nanoapp could be stuck waiting for a response
* but CHRE failed to enqueue one. For parameter details,
* @see postScanMonitorAsyncResultEvent
*/
void postScanMonitorAsyncResultEventFatal(
uint32_t nanoappInstanceId, bool success, bool enable, uint8_t errorCode,
const void *cookie);
/**
* Posts an event to a nanoapp indicating the result of a request for an
* active wifi scan.
*
* @param nanoappInstanceId The nanoapp instance ID to direct the event to.
* @param success If the request for a wifi resource was successful.
* @param errorCode The error code when success is set to false.
* @param cookie The cookie to be provided to the nanoapp. This is
* round-tripped from the nanoapp to provide context.
* @return true if the event was successfully posted to the event loop.
*/
bool postScanRequestAsyncResultEvent(
uint32_t nanoappInstanceId, bool success, uint8_t errorCode,
const void *cookie);
/**
* Calls through to postScanRequestAsyncResultEvent but invokes the
* FATAL_ERROR macro if the event is not posted successfully. This is used in
* asynchronous contexts where a nanoapp could be stuck waiting for a response
* but CHRE failed to enqueue one. For parameter details,
* @see postScanRequestAsyncResultEvent
*/
void postScanRequestAsyncResultEventFatal(
uint32_t nanoappInstanceId, bool success, uint8_t errorCode,
const void *cookie);
/**
* Posts a broadcast event containing the results of a wifi scan. Failure to
* post this event is a FATAL_ERROR. This is unrecoverable as the nanoapp will
* be stuck waiting for wifi scan results but there may be a gap.
*
* @param event the wifi scan event.
*/
void postScanEventFatal(chreWifiScanEvent *event);
/**
* Handles the result of a request to PlatformWifi to change the state of the
* scan monitor. See the handleScanMonitorStateChange method which may be
* called from any thread. This method is intended to be invoked on the CHRE
* event loop thread.
*
* @param enabled true if the result of the operation was an enabled scan
* monitor.
* @param errorCode an error code that is provided to indicate success or what
* type of error has occurred. See the chreError enum in the CHRE API
* for additional details.
*/
void handleScanMonitorStateChangeSync(bool enabled, uint8_t errorCode);
/**
* Handles the result of a request to PlatformWifi to perform an active WiFi
* scan. See the handleScanResponse method which may be called from any
* thread. This method is intended to be invoked on the CHRE event loop
* thread.
*
* @param enabled true if the result of the operation was an enabled scan
* monitor.
* @param errorCode an error code that is provided to indicate success or what
* type of error has occurred. See the chreError enum in the CHRE API
* for additional details.
*/
void handleScanResponseSync(bool pending, uint8_t errorCode);
/**
* Handles a WiFi scan event. See the handleScanEvent method with may be
* called from any thread. This method is intended to be invoked on the CHRE
* event loop thread.
*
* @param event The wifi event to distribute to nanoapps.
*/
void handleScanEventSync(chreWifiScanEvent *event);
/**
* TODO: this.
*/
void handleFreeWifiScanEvent(chreWifiScanEvent *scanEvent);
/**
* Releases the memory associated with an asynchronous wifi event.
*
* @param eventType The type of event being freed.
* @param eventData A pointer to the data to release.
*/
static void freeWifiAsyncResultCallback(uint16_t eventType, void *eventData);
/**
* Releases a wifi scan event after nanoapps have consumed it.
*
* @param eventType the type of event being freed.
* @param eventData a pointer to the scan event to release.
*/
static void freeWifiScanEventCallback(uint16_t eventType, void *eventData);
};
} // namespace chre
#endif // CHRE_CORE_WIFI_REQUEST_MANAGER_H_