1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_PAL_WIFI_SCAN_CACHE_H_
18 #define CHRE_PAL_WIFI_SCAN_CACHE_H_
19 
20 /**
21  * @file
22  * Defines a WiFi scan caching library that may be used beneath the CHRE WiFi
23  * PAL layer.
24  *
25  * This library should be used by the CHRE WiFi PAL implementation as a
26  * convenience module to store completed WiFi scan results, and provide them to
27  * CHRE as defined by the CHRE WiFi PAL API. If this library is used, there is
28  * no need to invoke the chrePalWifiCallback functions related to WiFi scans
29  * (e.g. scanResponseCallback()/scanEventCallback()) directly, as it will be
30  * performed by the caching library.
31  *
32  * The memory footprint of this library can be controlled at compile-time using
33  * macros. For instance, CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY can be adjusted to
34  * reduce the size of the cache storage.
35  *
36  * @see chreWifiScanCacheScanEventBegin() for how to cache scan results.
37  */
38 
39 #include <stdbool.h>
40 #include <stdint.h>
41 
42 #include "chre/pal/wifi.h"
43 #include "chre_api/chre/wifi.h"
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 //! The number of chreWifiScanResult items that will be stored in the scan
50 //! cache library.
51 #ifndef CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY
52 #define CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY 255
53 #endif
54 
55 //! The maximum value of chreWifiScanEvent.resultCount that will be used
56 //! in the scan cache library to send results to CHRE.
57 #ifndef CHRE_PAL_WIFI_SCAN_CACHE_MAX_RESULT_COUNT
58 #define CHRE_PAL_WIFI_SCAN_CACHE_MAX_RESULT_COUNT 20
59 #endif
60 
61 /**
62  * Initializes the WiFi scan cache.
63  *
64  * Only one scan cache library can be instantiated per compilation unit, and is
65  * not thread safe.
66  *
67  * This method must be invoked as a result of a chrePalWiFiApi->open() call.
68  *
69  * @param systemApi A non-null pointer to the system API functions.
70  * @param callbacks A non-null pointer to the callback functions.
71  *
72  * @return true if successfully initialized.
73  */
74 bool chreWifiScanCacheInit(const struct chrePalSystemApi *systemApi,
75                            const struct chrePalWifiCallbacks *callbacks);
76 
77 /**
78  * This method must be invoked as a result of a chrePalWifiApi->close() call.
79  */
80 void chreWifiScanCacheDeinit(void);
81 
82 /**
83  * Begins the caching of results from a single WiFi scan.
84  *
85  * This method must be invoked as a result of a WLAN performing a WiFi scan
86  * (either due to a request from CHRE or otherwise if scan monitoring is
87  * enabled).
88  *
89  * When a WiFi scan is performed, the following is the expected flow:
90  * 1. Invoke chreWifiScanCacheScanEventBegin() to start the cache.
91  * 2. For each successful WiFi scan result, invoke
92  * chreWifiScanCacheScanEventAdd(). If the scan is unsuccessful or no WiFi APs
93  * are scanned, this step is optional.
94  * 3. When the WiFi scan is completed (or failed), invoke
95  * chreWifiScanCacheScanEventEnd().
96  *
97  * This function must not be invoked while a scan caching is currently taking
98  * place (i.e. until chreWifiScanCacheScanEventEnd() is invoked).
99  *
100  * @param activeScanResult true if this WiFi scan was a result of an active WiFi
101  * scan from CHRE (i.e. not a result of passive scan monitoring only). If true,
102  * a scanResponseCallback will be invoked in chreWifiScanCacheScanEventEnd().
103  *
104  * @return true if the scan cache was successfully started.
105  *
106  * @see The fields of chreWifiScanEvent for the other parameters.
107  */
108 bool chreWifiScanCacheScanEventBegin(enum chreWifiScanType scanType,
109                                      uint8_t ssidSetSize,
110                                      const uint32_t *scannedFreqList,
111                                      uint16_t scannedFreqListLength,
112                                      uint8_t radioChainPref,
113                                      bool activeScanResult);
114 
115 /**
116  * Adds a WiFi scan result to the current WiFi scan event cache.
117  *
118  * This method must only be invoked after chreWifiScanCacheScanEventBegin()
119  * and before chreWifiScanCacheScanEventEnd(), otherwise has no effect.
120  * When this method is invoked, the provided result is stored in the current
121  * WiFi scan cache. The cache library may drop scan results if it is out of
122  * memory (decided by the CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY value).
123  *
124  * The function does not obtain ownership of the provided pointer.
125  *
126  * This function must be invoked as soon as the scan result is available (i.e
127  * the access point is detected). The chreWifiScanResult.ageMs field is
128  * ignored by the scan cache library, and will be populated internally when
129  * chreWifiScanCacheScanEventEnd() is invoked.
130  *
131  * @param result A non-null pointer to a WiFi scan result.
132  *
133  * @see chreWifiScanCacheScanEventBegin for the expected flow.
134  */
135 void chreWifiScanCacheScanEventAdd(const struct chreWifiScanResult *result);
136 
137 /**
138  * Ends the caching of a single scan event.
139  *
140  * This method must be invoked when a WiFi scan event is fully completed. This
141  * method will take the cached scan results and provide them (if any) to CHRE
142  * through the chrePalWifiCallbacks provided in chreWifiScanCacheInit().
143  *
144  * Note that this function may be directly invoked after
145  * chreWifiScanCacheScanEventBegin() without chreWifiScanCacheScanEventAdd() if
146  * the scanning failed.
147  *
148  * @param errorCode The error code of the scan operation.
149  *
150  * @see chreWifiScanCacheScanEventBegin for the expected flow.
151  */
152 void chreWifiScanCacheScanEventEnd(enum chreError errorCode);
153 
154 /**
155  * Checks if a new scan request from CHRE must be dispatched from the cache,
156  * and dispatches them through the chrePalWifiCallbacks if appropriate.
157  *
158  * This method will look at the currently completed WiFi scans and checks if the
159  * cache is within the maxScanAgeMs field of the scan parameter. If this method
160  * returns false, the current cache does not meet the maxScanAgeMs requirement,
161  * and the WLAN must perform a fresh scan.
162  *
163  * This method must be invoked when by the chrePalWifiApi->requestScan()
164  * implementation to see if a cached WiFi scan event can be used. An example
165  * usage is the following:
166  *
167  * if (chreWifiScanCacheDispatchFromCache(params)) {
168  *   // Cached WiFi scan event was dispatched - no need to perform fresh scan
169  *   // and can return a synchronous success.
170  *   return true;
171  * } else {
172  *   // Perform WiFi scan
173  * }
174  *
175  * @param params The chreWifiScanParams parameter of a scan request from CHRE.
176  *
177  * @return true if a scan was dispatched from the cache, false otherwise.
178  */
179 bool chreWifiScanCacheDispatchFromCache(
180     const struct chreWifiScanParams *params);
181 
182 /**
183  * Invoked to free a WiFi scan event produced by this caching library.
184  *
185  * This method must invoked by the chrePalWifiApi->releaseScanEvent()
186  * implementation if the caching library was used to send WiFi scan events.
187  */
188 void chreWifiScanCacheReleaseScanEvent(struct chreWifiScanEvent *event);
189 
190 /**
191  * Configures scan monitoring for the cache scan library.
192  *
193  * This method must be invoked by the chrePalWifiApi->configureScanMonitor()
194  * implementation.
195  *
196  * If scan monitoring is enabled, the cache scan library will send WiFi scan
197  * events provided through chreWifiScanCacheScanEventAdd() even if no
198  * outstanding request from CHRE is present.
199  *
200  * @param enable true to enable WiFi scan monitoring, false otherwise.
201  */
202 void chreWifiScanCacheConfigureScanMonitor(bool enable);
203 
204 #ifdef __cplusplus
205 }
206 #endif
207 
208 #endif  // CHRE_PAL_WIFI_SCAN_CACHE_H_
209