1 /*
2  * Copyright (C) 2016 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_H_
18 #define CHRE_PAL_WIFI_H_
19 
20 /**
21  * @file
22  * Defines the interface between the common CHRE core system and the
23  * platform-specific WiFi module.
24  */
25 
26 #include <stdbool.h>
27 #include <stdint.h>
28 
29 #include "chre/pal/system.h"
30 #include "chre/pal/version.h"
31 #include "chre_api/chre/common.h"
32 #include "chre_api/chre/wifi.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /**
39  * Initial version of the CHRE WiFi PAL, tied to CHRE API v1.1.
40  */
41 #define CHRE_PAL_WIFI_API_V1_0 CHRE_PAL_CREATE_API_VERSION(1, 0)
42 
43 // v1.1 skipped to avoid confusion with CHRE API v1.1
44 
45 /**
46  * Introduced alongside CHRE API v1.2, adding support for RTT ranging and radio
47  * chain preference.
48  */
49 #define CHRE_PAL_WIFI_API_V1_2 CHRE_PAL_CREATE_API_VERSION(1, 2)
50 
51 /**
52  * Introduced alongside CHRE API v1.5, adding support for additional WiFi
53  * security modes.
54  */
55 #define CHRE_PAL_WIFI_API_V1_5 CHRE_PAL_CREATE_API_VERSION(1, 5)
56 
57 /**
58  * The version of the WiFi PAL defined in this header file.
59  */
60 #define CHRE_PAL_WIFI_API_CURRENT_VERSION CHRE_PAL_WIFI_API_V1_5
61 
62 struct chrePalWifiCallbacks {
63   /**
64    * Callback invoked to inform the CHRE of the result of changes to the scan
65    * monitor registration status requested via configureScanMonitor in struct
66    * chrePalWifiApi.
67    *
68    * Unsolicited calls to this function must not be made. In other words,
69    * this callback should only be invoked as the direct result of an earlier
70    * call to configureScanMonitor. If the scan monitor registration is lost,
71    * for example due to a reset of the WiFi subsystem, then the PAL
72    * implementation is required to silently re-register the scan monitor when
73    * it recovers, as needed.
74    *
75    * @param enabled true if the scan monitor is currently active and
76    *        scanEventCallback will receive unsolicited scan results, false
77    *        otherwise
78    * @param errorCode An error code from enum chreError
79    *
80    * @see chrePalWifiApi.configureScanMonitor
81    * @see #chreError
82    */
83   void (*scanMonitorStatusChangeCallback)(bool enabled, uint8_t errorCode);
84 
85   /**
86    * Callback invoked to inform the CHRE of the result of a request for a
87    * scan requested via requestScan in struct chrePalWifiApi.
88    *
89    * Unsolicited calls to this function must not be made. See
90    * scanMonitorStatusChangeCallback() for more information.
91    *
92    * This function must only be called after the final status of the scan
93    * request is known. For example, it must not be called at the point when
94    * the scan is initially scheduled if it can still fail prior to delivering
95    * a result.
96    *
97    * @param pending true if the request was successful and the results of the
98    *        scan are pending delivery (via scanEventCallback), false otherwise
99    * @param errorCode An error code from enum chreError
100    */
101   void (*scanResponseCallback)(bool pending, uint8_t errorCode);
102 
103   /**
104    * Callback used to pass scan results from the WiFi module to the core CHRE
105    * system, which distributes it to clients (nanoapps).
106    *
107    * This function call passes ownership of the event memory to the core CHRE
108    * system, i.e. the PAL module must not modify the referenced data until the
109    * associated API function is called to release the memory.
110    *
111    * If the results of a given scan are be split across multiple events, and
112    * therefore multiple calls to this callback, then the events must be
113    * delivered in order, and in one contiguous series of callbacks with no
114    * interleaving of events that correspond to any other scan.
115    *
116    * The PAL module must not deliver the same scan event twice. As a specific
117    * example: if an explicit scan request is made via requestScan(), the PAL
118    * implementation must not redeliver the result a second time because scan
119    * monitoring is enabled.
120    *
121    * @param event Event data to distribute to clients. The WiFi module
122    *        must ensure that this memory remains accessible until it is passed
123    *        to the releaseScanEvent() function in struct chrePalWifiApi.
124    *
125    * @see chrePalWifiApi.configureScanMonitor
126    * @see chrePalWifiApi.requestScan
127    */
128   void (*scanEventCallback)(struct chreWifiScanEvent *event);
129 
130   /**
131    * Callback used to pass RTT ranging results from the WiFi module to the
132    * core CHRE system, which distributes it to clients (nanoapps).
133    *
134    * Like scanEventCallback, this function call passes ownership of the event
135    * memory to the core CHRE system.
136    *
137    * Only valid if requestedApiVersion given to chrePalWifiGetApi() is greater
138    * than or equal to CHRE_PAL_WIFI_API_V1_2.
139    *
140    * @param errorCode An error code from enum chreError, with CHRE_ERROR_NONE
141    *        indicating successful completion of the ranging operation
142    * @param event Event data to distribute to clients. Unlike with scan
143    *        events, RTT ranging results must be provided for all requested MAC
144    *        addresses in a single event. Ignored and may be NULL if errorCode
145    *        is not CHRE_ERROR_NONE.
146    *
147    * @since v1.2
148    */
149   void (*rangingEventCallback)(uint8_t errorCode,
150                                struct chreWifiRangingEvent *event);
151 };
152 
153 struct chrePalWifiApi {
154   /**
155    * Version of the module providing this API. This value should be
156    * constructed from CHRE_PAL_CREATE_MODULE_VERSION using the supported
157    * API version constant (CHRE_PAL_WIFI_API_*) and the module-specific patch
158    * version.
159    */
160   uint32_t moduleVersion;
161 
162   /**
163    * Initializes the WiFi module. Initialization must complete synchronously.
164    *
165    * @param systemApi Structure containing CHRE system function pointers which
166    *        the PAL implementation should prefer to use over equivalent
167    *        functionality exposed by the underlying platform. The module does
168    *        not need to deep-copy this structure; its memory remains
169    *        accessible at least until after close() is called.
170    * @param callbacks Structure containing entry points to the core CHRE
171    *        system. The module does not need to deep-copy this structure; its
172    *        memory remains accessible at least until after close() is called.
173    *
174    * @return true if initialization was successful, false otherwise
175    */
176   bool (*open)(const struct chrePalSystemApi *systemApi,
177                const struct chrePalWifiCallbacks *callbacks);
178 
179   /**
180    * Performs clean shutdown of the WiFi module, usually done in preparation
181    * for stopping the CHRE. The WiFi module must ensure that it will not
182    * invoke any callbacks past this point, and complete any relevant teardown
183    * activities before returning from this function.
184    */
185   void (*close)(void);
186 
187   //! @see chreWifiGetCapabilities()
188   uint32_t (*getCapabilities)(void);
189 
190   /**
191    * Configures whether the scanEventCallback receives unsolicited scan
192    * results, i.e. the results of scans not performed at the request of CHRE.
193    *
194    * While not expected, a duplicate request, e.g. one that requests to enable
195    * scan monitoring when it is already enabled, must follow the successful
196    * callback flow.
197    *
198    * @param enable true to enable listening for all available scan results
199    *
200    * @return true if the request was accepted for processing, in which case a
201    *         subsequent call to scanMonitorStatusChangeCallback will be used
202    *         to communicate the result of the operation
203    *
204    * @see chreWifiConfigureScanMonitorAsync()
205    */
206   bool (*configureScanMonitor)(bool enable);
207 
208   /**
209    * Request that the WiFi chipset perform a scan, or deliver results from its
210    * cache if the parameters allow for it. If this function returns true, then
211    * the scanResponseCallback will be invoked to provide the result of the
212    * scan. If that indicates a successful result (the scan data is pending),
213    * then scanEventCallback() will be invoked one more more times to deliver
214    * the results of the scan. The results for the requested scan are delivered
215    * in scanEventCallback() regardless of the most recent setting passed to
216    * configureScanMonitor().
217    *
218    * The asynchronous flow of a scan request made through this API is
219    * as follows:
220    *
221    *  1. requestScan() called, returns true if request accepted, otherwise
222    *     false (in which case the request fails at this stage and further
223    *     steps do not occur)
224    *  2. Scan is performed, or an error is encountered preventing the
225    *     successful delivery of the scan result
226    *  3. scanResponseCallback() is invoked to indicate whether the scan
227    *     succeeded, or the reason for failure (in which case the request fails
228    *     at this stage and further steps do not occur)
229    *  4. scanEventCallback() is invoked 1 or more times (even if the scan
230    *     resulted in no visible APs)
231    *
232    * Note that the callbacks in steps 3 and 4 must complete in the sequence
233    * given, and the call(s) to scanEventCallback() occurring immediately after
234    * scanResponseCallback() must be associated with this scan request, and not
235    * results delivered pursuant to an active scan monitor registration.
236    *
237    * This function must follow the CHRE API-defined behavior regarding
238    * timeouts. In other words, if a successful scan result is not produced by
239    * the lower layers within CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS,
240    * scanResponseCallback() must be invoked to indicate the failure, and any
241    * late arriving scan result from the lower layers must be dropped.
242    *
243    * At most 1 scan can be in progress from this API at any given time.
244    * In other words, the implementation should return false if another scan
245    * initiated via this function has not completed, i.e. it has not failed
246    * yet, or the final scan event has not yet been delivered via
247    * scanEventCallback(). However, this function must accept and queue a scan
248    * request made from this API while a scan requested by another client, such
249    * as the applications processor, is in progress.
250    *
251    * @param params See chreWifiRequestScanAsync(). If requestedApiVersion
252    *        supplied to chrePalWifiGetApi is at least CHRE_PAL_WIFI_API_V1_2,
253    *        then the new "radioChainPref" parameter will be included.
254    *
255    * @return true if the request was accepted for further processing, in which
256    *         case a subsequent call to scanResponseCallback will be used to
257    *         communicate the result of the operation
258    *
259    * @see #chreWifiScanParams
260    * @see chreWifiRequestScanAsync()
261    */
262   bool (*requestScan)(const struct chreWifiScanParams *params);
263 
264   /**
265    * Invoked when the core CHRE system no longer needs a WiFi scan event
266    * structure that was provided to it via scanEventCallback()
267    *
268    * @param event Event data to release
269    */
270   void (*releaseScanEvent)(struct chreWifiScanEvent *event);
271 
272   /**
273    * Request that the WiFi chipset perform RTT ranging against a set of access
274    * points specified in params. If this function returns true, then
275    * rangingEventCallback must be invoked once to deliver the final result of
276    * the operation, with the accompanying result structure if ranging was
277    * performed.
278    *
279    * RTT functionality in CHRE is based off the Android HAL definitions
280    * (hardware/interfaces/wifi/1.0/), but with less parameters. For
281    * example, CHRE only supports ranging against access points, and two-sided
282    * RTT. When mapping struct chreWifiRangingTarget into the equivalent fields
283    * defined in the HAL in struct RttConfig, the following default values
284    * should be used to fill the fields not specified in the CHRE structure:
285    *
286    * <pre>
287    *   type = TWO_SIDED
288    *   peer = AP
289    *   burstPeriod = 0
290    *   numBurst = 0
291    *   numFramesPerBurst = 8
292    *   numRetriesPerRttFrame = 0
293    *   numRetriesPerFtmr = 0
294    *   mustRequestLci = true
295    *   mustRequestLcr = false (can be true, but not exposed by CHRE)
296    *   burstDuration = 15
297    *   preamble = implementation-dependent**
298    *   bw = implementation-dependent**
299    * </pre>
300    *
301    * **These are used to populate the Format And Bandwidth field in the Fine
302    *   Timing Measurement Parameters element. Per the specification, proposed
303    *   values must fall within the capabilities of the requesting device, and
304    *   the configuration used is ultimately negotiated with the responding
305    *   STA. Therefore, it is up to the underlying WiFi implementation to pick
306    *   suitable values.
307    *
308    * Like {@link #requestScan}, this function must follow the CHRE API-defined
309    * behavior regarding timeouts, indicating failure via rangingEventCallback
310    * if the lower layers do not produce a result within
311    * CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS.
312    *
313    * Also like {@link #requestScan}, at most 1 RTT ranging request can be in
314    * progress from this API at any given time. Implementations should return
315    * false if this condition is not met, but must queue a request made from
316    * this API while a request from another client, such as the applications
317    * processor, is in progress.
318    *
319    * @return true if the request was accepted for further processing, in which
320    *         case a subsequent call to rangingEventCallback will be used to
321    *         communicate the result of the operation
322    *
323    * @see #chreWifiRangingParams
324    * @see chreWifiRequestRangingAsync()
325    *
326    * @since v1.2
327    */
328   bool (*requestRanging)(const struct chreWifiRangingParams *params);
329 
330   /**
331    * Invoked when the core CHRE system no longer needs a WiFi ranging result
332    * event structure that was provided to it via rangingEventCallback()
333    *
334    * @param event Event data to release
335    *
336    * @since v1.2
337    */
338   void (*releaseRangingEvent)(struct chreWifiRangingEvent *event);
339 };
340 
341 /**
342  * Retrieve a handle for the CHRE WiFi PAL.
343  *
344  * @param requestedApiVersion The implementation of this function must return a
345  *        pointer to a structure with the same major version as requested.
346  *
347  * @return Pointer to API handle, or NULL if a compatible API version is not
348  *         supported by the module, or the API as a whole is not implemented. If
349  *         non-NULL, the returned API handle must be valid as long as this
350  *         module is loaded.
351  */
352 const struct chrePalWifiApi *chrePalWifiGetApi(uint32_t requestedApiVersion);
353 
354 #ifdef __cplusplus
355 }
356 #endif
357 
358 #endif  // CHRE_PAL_WIFI_H_
359