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