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_WIFI_H_
18 #define _CHRE_WIFI_H_
19 
20 /**
21  * @file
22  * WiFi (IEEE 802.11) API, currently covering scanning features useful for
23  * determining location and offloading certain connectivity scans.
24  *
25  * In this file, specification references use the following shorthand:
26  *
27  *    Shorthand | Full specification name
28  *   ---------- | ------------------------
29  *     "802.11" | IEEE Std 802.11-2007
30  *     "HT"     | IEEE Std 802.11n-2009
31  *     "VHT"    | IEEE Std 802.11ac-2013
32  *     "WiFi 6" | IEEE Std 802.11ax draft
33  *
34  * In the current version of CHRE API, the 6GHz band introduced in WiFi 6 is
35  * not supported. A scan request from CHRE should not result in scanning 6GHz
36  * channels. In particular, if a 6GHz channel is specified in scanning or
37  * ranging request parameter, CHRE should return an error code of
38  * CHRE_ERROR_NOT_SUPPORTED. Additionally, CHRE implementations must not include
39  * observations of access points on 6GHz channels in scan results, especially
40  * those produced due to scan monitoring.
41  */
42 
43 #include <chre/common.h>
44 
45 #include <stdbool.h>
46 #include <stddef.h>
47 #include <stdint.h>
48 #include <string.h>
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 /**
55  * The set of flags returned by chreWifiGetCapabilities().
56  * @defgroup CHRE_WIFI_CAPABILITIES
57  * @{
58  */
59 
60 //! No WiFi APIs are supported
61 #define CHRE_WIFI_CAPABILITIES_NONE             UINT32_C(0)
62 
63 //! Listening to scan results is supported, as enabled via
64 //! chreWifiConfigureScanMonitorAsync()
65 #define CHRE_WIFI_CAPABILITIES_SCAN_MONITORING  UINT32_C(1 << 0)
66 
67 //! Requesting WiFi scans on-demand is supported via chreWifiRequestScanAsync()
68 #define CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN   UINT32_C(1 << 1)
69 
70 //! Specifying the radio chain preference in on-demand scan requests, and
71 //! reporting it in scan events is supported
72 //! @since v1.2
73 #define CHRE_WIFI_CAPABILITIES_RADIO_CHAIN_PREF  UINT32_C(1 << 2)
74 
75 //! Requesting RTT ranging is supported via chreWifiRequestRangingAsync()
76 //! @since v1.2
77 #define CHRE_WIFI_CAPABILITIES_RTT_RANGING      UINT32_C(1 << 3)
78 
79 /** @} */
80 
81 /**
82  * Produce an event ID in the block of IDs reserved for WiFi
83  * @param offset  Index into WiFi event ID block; valid range [0,15]
84  */
85 #define CHRE_WIFI_EVENT_ID(offset)  (CHRE_EVENT_WIFI_FIRST_EVENT + (offset))
86 
87 /**
88  * nanoappHandleEvent argument: struct chreAsyncResult
89  *
90  * Communicates the asynchronous result of a request to the WiFi API. The
91  * requestType field in {@link #chreAsyncResult} is set to a value from enum
92  * chreWifiRequestType.
93  */
94 #define CHRE_EVENT_WIFI_ASYNC_RESULT  CHRE_WIFI_EVENT_ID(0)
95 
96 /**
97  * nanoappHandleEvent argument: struct chreWifiScanEvent
98  *
99  * Provides results of a WiFi scan.
100  */
101 #define CHRE_EVENT_WIFI_SCAN_RESULT  CHRE_WIFI_EVENT_ID(1)
102 
103 /**
104  * nanoappHandleEvent argument: struct chreWifiRangingEvent
105  *
106  * Provides results of an RTT ranging request.
107  */
108 #define CHRE_EVENT_WIFI_RANGING_RESULT  CHRE_WIFI_EVENT_ID(2)
109 
110 // NOTE: Do not add new events with ID > 15; only values 0-15 are reserved
111 // (see chre/event.h)
112 
113 /**
114  * The maximum amount of time that is allowed to elapse between a call to
115  * chreWifiRequestScanAsync() that returns true, and the associated
116  * CHRE_EVENT_WIFI_ASYNC_RESULT used to indicate whether the scan completed
117  * successfully or not.
118  */
119 #define CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS  (30 * CHRE_NSEC_PER_SEC)
120 
121 /**
122  * The maximum amount of time that is allowed to elapse between a call to
123  * chreWifiRequestRangingAsync() that returns true, and the associated
124  * CHRE_EVENT_WIFI_RANGING_RESULT used to indicate whether the ranging operation
125  * completed successfully or not.
126  */
127 #define CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS  (30 * CHRE_NSEC_PER_SEC)
128 
129 /**
130  * The current compatibility version of the chreWifiScanEvent structure,
131  * including nested structures.
132  */
133 #define CHRE_WIFI_SCAN_EVENT_VERSION  UINT8_C(1)
134 
135 /**
136  * The current compatibility version of the chreWifiRangingEvent structure,
137  * including nested structures.
138  */
139 #define CHRE_WIFI_RANGING_EVENT_VERSION  UINT8_C(0)
140 
141 /**
142  * Maximum number of frequencies that can be explicitly specified when
143  * requesting a scan
144  * @see #chreWifiScanParams
145  */
146 #define CHRE_WIFI_FREQUENCY_LIST_MAX_LEN  (20)
147 
148 /**
149  * Maximum number of SSIDs that can be explicitly specified when requesting a
150  * scan
151  * @see #chreWifiScanParams
152  */
153 #define CHRE_WIFI_SSID_LIST_MAX_LEN  (20)
154 
155 /**
156  * The maximum number of devices that can be specified in a single RTT ranging
157  * request.
158  * @see #chreWifiRangingParams
159  */
160 #define CHRE_WIFI_RANGING_LIST_MAX_LEN  (10)
161 
162 /**
163  * The maximum number of octets in an SSID (see 802.11 7.3.2.1)
164  */
165 #define CHRE_WIFI_SSID_MAX_LEN  (32)
166 
167 /**
168  * The number of octets in a BSSID (see 802.11 7.1.3.3.3)
169  */
170 #define CHRE_WIFI_BSSID_LEN  (6)
171 
172 /**
173  * Set of flags which can either indicate a frequency band. Specified as a bit
174  * mask to allow for combinations in future API versions.
175  * @defgroup CHRE_WIFI_BAND_MASK
176  * @{
177  */
178 
179 #define CHRE_WIFI_BAND_MASK_2_4_GHZ  UINT8_C(1 << 0)  //!< 2.4 GHz
180 #define CHRE_WIFI_BAND_MASK_5_GHZ    UINT8_C(1 << 1)  //!< 5 GHz
181 
182 /** @} */
183 
184 /**
185  * Characteristics of a scanned device given in struct chreWifiScanResult.flags
186  * @defgroup CHRE_WIFI_SCAN_RESULT_FLAGS
187  * @{
188  */
189 
190 #define CHRE_WIFI_SCAN_RESULT_FLAGS_NONE                         UINT8_C(0)
191 
192 //! Element ID 61 (HT Operation) is present (see HT 7.3.2)
193 #define CHRE_WIFI_SCAN_RESULT_FLAGS_HT_OPS_PRESENT               UINT8_C(1 << 0)
194 
195 //! Element ID 192 (VHT Operation) is present (see VHT 8.4.2)
196 #define CHRE_WIFI_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT              UINT8_C(1 << 1)
197 
198 //! Element ID 127 (Extended Capabilities) is present, and bit 70 (Fine Timing
199 //! Measurement Responder) is set to 1 (see IEEE Std 802.11-2016 9.4.2.27)
200 #define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER             UINT8_C(1 << 2)
201 
202 //! Retained for backwards compatibility
203 //! @see CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER
204 #define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_80211MC_RTT_RESPONDER \
205     CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER
206 
207 //! HT Operation element indicates that a secondary channel is present
208 //! (see HT 7.3.2.57)
209 #define CHRE_WIFI_SCAN_RESULT_FLAGS_HAS_SECONDARY_CHANNEL_OFFSET UINT8_C(1 << 3)
210 
211 //! HT Operation element indicates that the secondary channel is below the
212 //! primary channel (see HT 7.3.2.57)
213 #define CHRE_WIFI_SCAN_RESULT_FLAGS_SECONDARY_CHANNEL_OFFSET_IS_BELOW  \
214                                                                  UINT8_C(1 << 4)
215 
216 /** @} */
217 
218 /**
219  * Identifies the authentication methods supported by an AP. Note that not every
220  * combination of flags may be possible. Based on WIFI_PNO_AUTH_CODE_* from
221  * hardware/libhardware_legacy/include/hardware_legacy/gscan.h in Android.
222  * @defgroup CHRE_WIFI_SECURITY_MODE_FLAGS
223  * @{
224  */
225 
226 #define CHRE_WIFI_SECURITY_MODE_UNKONWN  UINT8_C(0)
227 
228 #define CHRE_WIFI_SECURITY_MODE_OPEN  UINT8_C(1 << 0)  //!< No auth/security
229 #define CHRE_WIFI_SECURITY_MODE_WEP   UINT8_C(1 << 1)
230 #define CHRE_WIFI_SECURITY_MODE_PSK   UINT8_C(1 << 2)  //!< WPA-PSK or WPA2-PSK
231 #define CHRE_WIFI_SECURITY_MODE_EAP   UINT8_C(1 << 3)  //!< WPA-EAP or WPA2-EAP
232 
233 //! @since v1.5
234 #define CHRE_WIFI_SECURITY_MODE_SAE   UINT8_C(1 << 4)
235 
236 //! @since v1.5
237 #define CHRE_WIFI_SECURITY_MODE_EAP_SUITE_B  UINT8_C(1 << 5)
238 
239 //! @since v1.5
240 #define CHRE_WIFI_SECURITY_MODE_OWE   UINT8_C(1 << 6)
241 
242 /** @} */
243 
244 /**
245  * Identifies which radio chain was used to discover an AP. The underlying
246  * hardware does not necessarily support more than one radio chain.
247  * @defgroup CHRE_WIFI_RADIO_CHAIN_FLAGS
248  * @{
249  */
250 
251 #define CHRE_WIFI_RADIO_CHAIN_UNKNOWN  UINT8_C(0)
252 #define CHRE_WIFI_RADIO_CHAIN_0        UINT8_C(1 << 0)
253 #define CHRE_WIFI_RADIO_CHAIN_1        UINT8_C(1 << 1)
254 
255 /** @} */
256 
257 //! Special value indicating that an LCI uncertainty fields is not provided
258 //! Ref: RFC 6225
259 #define CHRE_WIFI_LCI_UNCERTAINTY_UNKNOWN  UINT8_C(0)
260 
261 /**
262  * Defines the flags that may be returned in
263  * {@link #chreWifiRangingResult.flags}. Undefined bits are reserved for future
264  * use and must be ignored by nanoapps.
265  * @defgroup CHRE_WIFI_RTT_RESULT_FLAGS
266  * @{
267  */
268 
269 //! If set, the nested chreWifiLci structure is populated; otherwise it is
270 //! invalid and must be ignored
271 #define CHRE_WIFI_RTT_RESULT_HAS_LCI  UINT8_C(1 << 0)
272 
273 /** @} */
274 
275 /**
276  * Identifies a WiFi frequency band
277  */
278 enum chreWifiBand {
279     CHRE_WIFI_BAND_2_4_GHZ = CHRE_WIFI_BAND_MASK_2_4_GHZ,
280     CHRE_WIFI_BAND_5_GHZ   = CHRE_WIFI_BAND_MASK_5_GHZ,
281 };
282 
283 /**
284  * Indicates the BSS operating channel width determined from the VHT and/or HT
285  * Operation elements. Refer to VHT 8.4.2.161 and HT 7.3.2.57.
286  */
287 enum chreWifiChannelWidth {
288     CHRE_WIFI_CHANNEL_WIDTH_20_MHZ         = 0,
289     CHRE_WIFI_CHANNEL_WIDTH_40_MHZ         = 1,
290     CHRE_WIFI_CHANNEL_WIDTH_80_MHZ         = 2,
291     CHRE_WIFI_CHANNEL_WIDTH_160_MHZ        = 3,
292     CHRE_WIFI_CHANNEL_WIDTH_80_PLUS_80_MHZ = 4,
293 };
294 
295 /**
296  * Indicates the type of scan requested or performed
297  */
298 enum chreWifiScanType {
299     //! Perform a purely active scan using probe requests. Do not scan channels
300     //! restricted to use via Dynamic Frequency Selection (DFS) only.
301     CHRE_WIFI_SCAN_TYPE_ACTIVE = 0,
302 
303     //! Perform an active scan on unrestricted channels, and also perform a
304     //! passive scan on channels that are restricted to use via Dynamic
305     //! Frequency Selection (DFS), e.g. the U-NII bands 5250-5350MHz and
306     //! 5470-5725MHz in the USA as mandated by FCC regulation.
307     CHRE_WIFI_SCAN_TYPE_ACTIVE_PLUS_PASSIVE_DFS = 1,
308 
309     //! Perform a passive scan, only listening for beacons.
310     CHRE_WIFI_SCAN_TYPE_PASSIVE = 2,
311 
312     //! Client has no preference for a particular scan type.
313     //! Only valid in a {@link #chreWifiScanParams}.
314     //!
315     //! On a v1.4 or earlier platform, this will fall back to
316     //! CHRE_WIFI_SCAN_TYPE_ACTIVE if {@link #chreWifiScanParams.channelSet} is
317     //! set to CHRE_WIFI_CHANNEL_SET_NON_DFS, and to
318     //! CHRE_WIFI_SCAN_TYPE_ACTIVE_PLUS_PASSIVE_DFS otherwise.
319     //!
320     //! If CHRE_WIFI_CAPABILITIES_RADIO_CHAIN_PREF is supported, a v1.5 or
321     //! later platform shall perform a type of scan optimized for {@link
322     //! #chreWifiScanParams.radioChainPref}.
323     //!
324     //! Clients are strongly encouraged to set this value in {@link
325     //! #chreWifiScanParams.scanType} and instead express their preferences
326     //! through {@link #chreWifiRadioChainPref} and {@link #chreWifiChannelSet}
327     //! so the platform can best optimize power and performance.
328     //!
329     //! @since v1.5
330     CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE = 3,
331 };
332 
333 /**
334  * Indicates whether RTT ranging with a specific device succeeded
335  */
336 enum chreWifiRangingStatus {
337     //! Ranging completed successfully
338     CHRE_WIFI_RANGING_STATUS_SUCCESS = 0,
339 
340     //! Ranging failed due to an unspecified error
341     CHRE_WIFI_RANGING_STATUS_ERROR   = 1,
342 };
343 
344 /**
345  * Possible values for {@link #chreWifiLci.altitudeType}. Ref: RFC 6225 2.4
346  */
347 enum chreWifiLciAltitudeType {
348     CHRE_WIFI_LCI_ALTITUDE_TYPE_UNKNOWN = 0,
349     CHRE_WIFI_LCI_ALTITUDE_TYPE_METERS  = 1,
350     CHRE_WIFI_LCI_ALTITUDE_TYPE_FLOORS  = 2,
351 };
352 
353 /**
354  * Indicates a type of request made in this API. Used to populate the resultType
355  * field of struct chreAsyncResult sent with CHRE_EVENT_WIFI_ASYNC_RESULT.
356  */
357 enum chreWifiRequestType {
358     CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR = 1,
359     CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN           = 2,
360     CHRE_WIFI_REQUEST_TYPE_RANGING                = 3,
361 };
362 
363 /**
364  * Allows a nanoapp to express its preference for how multiple available
365  * radio chains should be used when performing an on-demand scan. This is only a
366  * preference from the nanoapp and is not guaranteed to be honored by the WiFi
367  * firmware.
368  */
369 enum chreWifiRadioChainPref {
370     //! No preference for radio chain usage
371     CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT = 0,
372 
373     //! In a scan result, indicates that the radio chain preference used for the
374     //! scan is not known
375     CHRE_WIFI_RADIO_CHAIN_PREF_UNKNOWN = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
376 
377     //! Prefer to use available radio chains in a way that minimizes time to
378     //! complete the scan
379     CHRE_WIFI_RADIO_CHAIN_PREF_LOW_LATENCY = 1,
380 
381     //! Prefer to use available radio chains in a way that minimizes total power
382     //! consumed for the scan
383     CHRE_WIFI_RADIO_CHAIN_PREF_LOW_POWER = 2,
384 
385     //! Prefer to use available radio chains in a way that maximizes accuracy of
386     //! the scan result, e.g. RSSI measurements
387     CHRE_WIFI_RADIO_CHAIN_PREF_HIGH_ACCURACY = 3,
388 };
389 
390 /**
391  * SSID with an explicit length field, used when an array of SSIDs is supplied.
392  */
393 struct chreWifiSsidListItem {
394     //! Number of valid bytes in ssid. Valid range [0, CHRE_WIFI_SSID_MAX_LEN]
395     uint8_t ssidLen;
396 
397     //! Service Set Identifier (SSID)
398     uint8_t ssid[CHRE_WIFI_SSID_MAX_LEN];
399 };
400 
401 /**
402  * Indicates the set of channels to be scanned.
403  *
404  * @since v1.5
405  */
406 enum chreWifiChannelSet {
407     //! The set of channels that allows active scan using probe request.
408     CHRE_WIFI_CHANNEL_SET_NON_DFS = 0,
409 
410     //! The set of all channels supported.
411     CHRE_WIFI_CHANNEL_SET_ALL = 1,
412 };
413 
414 /**
415  * Data structure passed to chreWifiRequestScanAsync
416  */
417 struct chreWifiScanParams {
418     //! Set to a value from enum chreWifiScanType
419     uint8_t scanType;
420 
421     //! Indicates whether the client is willing to tolerate receiving cached
422     //! results of a previous scan, and if so, the maximum age of the scan that
423     //! the client will accept. "Age" in this case is defined as the elapsed
424     //! time between when the most recent scan was completed and the request is
425     //! received, in milliseconds. If set to 0, no cached results may be
426     //! provided, and all scan results must come from a "fresh" WiFi scan, i.e.
427     //! one that completes strictly after this request is received. If more than
428     //! one scan is cached and meets this age threshold, only the newest scan is
429     //! provided.
430     uint32_t maxScanAgeMs;
431 
432     //! If set to 0, scan all frequencies. Otherwise, this indicates the number
433     //! of frequencies to scan, as specified in the frequencyList array. Valid
434     //! range [0, CHRE_WIFI_FREQUENCY_LIST_MAX_LEN].
435     uint16_t frequencyListLen;
436 
437     //! Pointer to an array of frequencies to scan, given as channel center
438     //! frequencies in MHz. This field may be NULL if frequencyListLen is 0.
439     const uint32_t *frequencyList;
440 
441     //! If set to 0, do not restrict scan to any SSIDs. Otherwise, this
442     //! indicates the number of SSIDs in the ssidList array to be used for
443     //! directed probe requests. Not applicable and ignore when scanType is
444     //! CHRE_WIFI_SCAN_TYPE_PASSIVE.
445     uint8_t ssidListLen;
446 
447     //! Pointer to an array of SSIDs to use for directed probe requests. May be
448     //! NULL if ssidListLen is 0.
449     const struct chreWifiSsidListItem *ssidList;
450 
451     //! Set to a value from enum chreWifiRadioChainPref to specify the desired
452     //! trade-off between power consumption, accuracy, etc. If
453     //! chreWifiGetCapabilities() does not have the applicable bit set, this
454     //! parameter is ignored.
455     //! @since v1.2
456     uint8_t radioChainPref;
457 
458     //! Set to a value from enum chreWifiChannelSet to specify the set of
459     //! channels to be scanned. This field is considered by the platform only
460     //! if scanType is CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE and frequencyListLen
461     //! is equal to zero.
462     //!
463     //! @since v1.5
464     uint8_t channelSet;
465 };
466 
467 /**
468  * Provides information about a single access point (AP) detected in a scan.
469  */
470 struct chreWifiScanResult {
471     //! Number of milliseconds prior to referenceTime in the enclosing
472     //! chreWifiScanEvent struct when the probe response or beacon frame that
473     //! was used to populate this structure was received.
474     uint32_t ageMs;
475 
476     //! Capability Information field sent by the AP (see 802.11 7.3.1.4). This
477     //! field must reflect native byte order and bit ordering, such that
478     //! (capabilityInfo & 1) gives the bit for the ESS subfield.
479     uint16_t capabilityInfo;
480 
481     //! Number of valid bytes in ssid. Valid range [0, CHRE_WIFI_SSID_MAX_LEN]
482     uint8_t ssidLen;
483 
484     //! Service Set Identifier (SSID), a series of 0 to 32 octets identifying
485     //! the access point. Note that this is commonly a human-readable ASCII
486     //! string, but this is not the required encoding per the standard.
487     uint8_t ssid[CHRE_WIFI_SSID_MAX_LEN];
488 
489     //! Basic Service Set Identifier (BSSID), represented in big-endian byte
490     //! order, such that the first octet of the OUI is accessed in byte index 0.
491     uint8_t bssid[CHRE_WIFI_BSSID_LEN];
492 
493     //! A set of flags from CHRE_WIFI_SCAN_RESULT_FLAGS_*
494     uint8_t flags;
495 
496     //! RSSI (Received Signal Strength Indicator), in dBm. Typically negative.
497     //! If multiple radio chains were used to scan this AP, this is a "best
498     //! available" measure that may be a composite of measurements taken across
499     //! the radio chains.
500     int8_t  rssi;
501 
502     //! Operating band, set to a value from enum chreWifiBand
503     uint8_t band;
504 
505     /**
506      * Indicates the center frequency of the primary 20MHz channel, given in
507      * MHz. This value is derived from the channel number via the formula:
508      *
509      *     primaryChannel (MHz) = CSF + 5 * primaryChannelNumber
510      *
511      * Where CSF is the channel starting frequency (in MHz) given by the
512      * operating class/band (i.e. 2407 or 5000), and primaryChannelNumber is the
513      * channel number in the range [1, 200].
514      *
515      * Refer to VHT 22.3.14.
516      */
517     uint32_t primaryChannel;
518 
519     /**
520      * If the channel width is 20 MHz, this field is not relevant and set to 0.
521      * If the channel width is 40, 80, or 160 MHz, then this denotes the channel
522      * center frequency (in MHz). If the channel is 80+80 MHz, then this denotes
523      * the center frequency of segment 0, which contains the primary channel.
524      * This value is derived from the frequency index using the same formula as
525      * for primaryChannel.
526      *
527      * Refer to VHT 8.4.2.161, and VHT 22.3.14.
528      *
529      * @see #primaryChannel
530      */
531     uint32_t centerFreqPrimary;
532 
533     /**
534      * If the channel width is 80+80MHz, then this denotes the center frequency
535      * of segment 1, which does not contain the primary channel. Otherwise, this
536      * field is not relevant and set to 0.
537      *
538      * @see #centerFreqPrimary
539      */
540     uint32_t centerFreqSecondary;
541 
542     //! @see #chreWifiChannelWidth
543     uint8_t channelWidth;
544 
545     //! Flags from CHRE_WIFI_SECURITY_MODE_* indicating supported authentication
546     //! and associated security modes
547     //! @see CHRE_WIFI_SECURITY_MODE_FLAGS
548     uint8_t securityMode;
549 
550     //! Identifies the radio chain(s) used to discover this AP
551     //! @see CHRE_WIFI_RADIO_CHAIN_FLAGS
552     //! @since v1.2
553     uint8_t radioChain;
554 
555     //! If the CHRE_WIFI_RADIO_CHAIN_0 bit is set in radioChain, gives the RSSI
556     //! measured on radio chain 0 in dBm; otherwise invalid and set to 0. This
557     //! field, along with its relative rssiChain1, can be used to determine RSSI
558     //! measurements from each radio chain when multiple chains were used to
559     //! discover this AP.
560     //! @see #radioChain
561     //! @since v1.2
562     int8_t rssiChain0;
563     int8_t rssiChain1;  //!< @see #rssiChain0
564 
565     //! Reserved; set to 0
566     uint8_t reserved[7];
567 };
568 
569 /**
570  * Data structure sent with events of type CHRE_EVENT_WIFI_SCAN_RESULT.
571  */
572 struct chreWifiScanEvent {
573     //! Indicates the version of the structure, for compatibility purposes.
574     //! Clients do not normally need to worry about this field; the CHRE
575     //! implementation guarantees that the client only receives the structure
576     //! version it expects.
577     uint8_t version;
578 
579     //! The number of entries in the results array in this event. The CHRE
580     //! implementation may split scan results across multiple events for memory
581     //! concerns, etc.
582     uint8_t resultCount;
583 
584     //! The total number of results returned by the scan. Allows an event
585     //! consumer to identify when it has received all events associated with a
586     //! scan.
587     uint8_t resultTotal;
588 
589     //! Sequence number for this event within the series of events comprising a
590     //! complete scan result. Scan events are delivered strictly in order, i.e.
591     //! this is monotonically increasing for the results of a single scan. Valid
592     //! range [0, <number of events for scan> - 1]. The number of events for a
593     //! scan is typically given by
594     //! ceil(resultTotal / <max results per event supported by platform>).
595     uint8_t eventIndex;
596 
597     //! A value from enum chreWifiScanType indicating the type of scan performed
598     uint8_t scanType;
599 
600     //! If a directed scan was performed to a limited set of SSIDs, then this
601     //! identifies the number of unique SSIDs included in the probe requests.
602     //! Otherwise, this is set to 0, indicating that the scan was not limited by
603     //! SSID. Note that if this is non-zero, the list of SSIDs used is not
604     //! included in the scan event.
605     uint8_t ssidSetSize;
606 
607     //! If 0, indicates that all frequencies applicable for the scanType were
608     //! scanned. Otherwise, indicates the number of frequencies scanned, as
609     //! specified in scannedFreqList.
610     uint16_t scannedFreqListLen;
611 
612     //! Timestamp when the scan was completed, from the same time base as
613     //! chreGetTime() (in nanoseconds)
614     uint64_t referenceTime;
615 
616     //! Pointer to an array containing scannedFreqListLen values comprising the
617     //! set of frequencies that were scanned. Frequencies are specified as
618     //! channel center frequencies in MHz. May be NULL if scannedFreqListLen is
619     //! 0.
620     const uint32_t *scannedFreqList;
621 
622     //! Pointer to an array containing resultCount entries. May be NULL if
623     //! resultCount is 0.
624     const struct chreWifiScanResult *results;
625 
626     //! Set to a value from enum chreWifiRadioChainPref indicating the radio
627     //! chain preference used for the scan. If the applicable bit is not set in
628     //! chreWifiGetCapabilities(), this will always be set to
629     //! CHRE_WIFI_RADIO_CHAIN_PREF_UNKNOWN.
630     //! @since v1.2
631     uint8_t radioChainPref;
632 };
633 
634 /**
635  * Identifies a device to perform RTT ranging against. These values are normally
636  * populated based on the contents of a scan result.
637  * @see #chreWifiScanResult
638  * @see chreWifiRangingTargetFromScanResult()
639  */
640 struct chreWifiRangingTarget {
641     //! Device MAC address, specified in the same byte order as
642     //! {@link #chreWifiScanResult.bssid}
643     uint8_t macAddress[CHRE_WIFI_BSSID_LEN];
644 
645     //! Center frequency of the primary 20MHz channel, in MHz
646     //! @see #chreWifiScanResult.primaryChannel
647     uint32_t primaryChannel;
648 
649     //! Channel center frequency, in MHz, or 0 if not relevant
650     //! @see #chreWifiScanResult.centerFreqPrimary
651     uint32_t centerFreqPrimary;
652 
653     //! Channel center frequency of segment 1 if channel width is 80+80MHz,
654     //! otherwise 0
655     //! @see #chreWifiScanResult.centerFreqSecondary
656     uint32_t centerFreqSecondary;
657 
658     //! @see #chreWifiChannelWidth
659     uint8_t channelWidth;
660 
661     //! Reserved for future use and ignored by CHRE
662     uint8_t reserved[3];
663 };
664 
665 /**
666  * Parameters for an RTT ("Fine Timing Measurement" in terms of 802.11-2016)
667  * ranging request, supplied to chreWifiRequestRangingAsync().
668  */
669 struct chreWifiRangingParams {
670     //! Number of devices to perform ranging against and the length of
671     //! targetList, in range [1, CHRE_WIFI_RANGING_LIST_MAX_LEN]
672     uint8_t targetListLen;
673 
674     //! Array of macAddressListLen MAC addresses (e.g. BSSIDs) with which to
675     //! attempt RTT ranging
676     const struct chreWifiRangingTarget *targetList;
677 };
678 
679 /**
680  * Provides the result of RTT ranging with a single device.
681  */
682 struct chreWifiRangingResult {
683     //! Time when the ranging operation on this device was performed, in the
684     //! same time base as chreGetTime() (in nanoseconds)
685     uint64_t timestamp;
686 
687     //! MAC address of the device for which ranging was requested
688     uint8_t macAddress[CHRE_WIFI_BSSID_LEN];
689 
690     //! Gives the result of ranging to this device. If not set to
691     //! CHRE_WIFI_RANGING_STATUS_SUCCESS, the ranging attempt to this device
692     //! failed, and other fields in this structure may be invalid.
693     //! @see #chreWifiRangingStatus
694     uint8_t status;
695 
696     //! The mean RSSI measured during the RTT burst, in dBm. Typically negative.
697     //! If status is not CHRE_WIFI_RANGING_STATUS_SUCCESS, will be set to 0.
698     int8_t rssi;
699 
700     //! Estimated distance to the device with the given BSSID, in millimeters.
701     //! Generally the mean of multiple measurements performed in a single burst.
702     //! If status is not CHRE_WIFI_RANGING_STATUS_SUCCESS, will be set to 0.
703     uint32_t distance;
704 
705     //! Standard deviation of estimated distance across multiple measurements
706     //! performed in a single RTT burst, in millimeters. If status is not
707     //! CHRE_WIFI_RANGING_STATUS_SUCCESS, will be set to 0.
708     uint32_t distanceStdDev;
709 
710     //! Location Configuration Information (LCI) information optionally returned
711     //! during the ranging procedure. Only valid if {@link #flags} has the
712     //! CHRE_WIFI_RTT_RESULT_HAS_LCI bit set. Refer to IEEE 802.11-2016
713     //! 9.4.2.22.10, 11.24.6.7, and RFC 6225 (July 2011) for more information.
714     //! Coordinates are to be interpreted according to the WGS84 datum.
715     struct chreWifiLci {
716         //! Latitude in degrees as 2's complement fixed-point with 25 fractional
717         //! bits, i.e. degrees * 2^25. Ref: RFC 6225 2.3
718         int64_t latitude;
719 
720         //! Longitude, same format as {@link #latitude}
721         int64_t longitude;
722 
723         //! Altitude represented as a 2's complement fixed-point value with 8
724         //! fractional bits. Interpretation depends on {@link #altitudeType}. If
725         //! UNKNOWN, this field must be ignored. If *METERS, distance relative
726         //! to the zero point in the vertical datum. If *FLOORS, a floor value
727         //! relative to the ground floor, potentially fractional, e.g. to
728         //! indicate mezzanine levels. Ref: RFC 6225 2.4
729         int32_t altitude;
730 
731         //! Maximum extent of latitude uncertainty in degrees, decoded via this
732         //! formula: 2 ^ (8 - x) where "x" is the encoded value passed in this
733         //! field. Unknown if set to CHRE_WIFI_LCI_UNCERTAINTY_UNKNOWN.
734         //! Ref: RFC 6225 2.3.2
735         uint8_t latitudeUncertainty;
736 
737         //! @see #latitudeUncertainty
738         uint8_t longitudeUncertainty;
739 
740         //! Defines how to interpret altitude, set to a value from enum
741         //! chreWifiLciAltitudeType
742         uint8_t altitudeType;
743 
744         //! Uncertainty in altitude, decoded via this formula: 2 ^ (21 - x)
745         //! where "x" is the encoded value passed in this field. Unknown if set
746         //! to CHRE_WIFI_LCI_UNCERTAINTY_UNKNOWN. Only applies when altitudeType
747         //! is CHRE_WIFI_LCI_ALTITUDE_TYPE_METERS. Ref: RFC 6225 2.4.5
748         uint8_t altitudeUncertainty;
749     } lci;
750 
751     //! Refer to CHRE_WIFI_RTT_RESULT_FLAGS
752     uint8_t flags;
753 
754     //! Reserved; set to 0
755     uint8_t reserved[7];
756 };
757 
758 /**
759  * Data structure sent with events of type CHRE_EVENT_WIFI_RANGING_RESULT.
760  */
761 struct chreWifiRangingEvent {
762     //! Indicates the version of the structure, for compatibility purposes.
763     //! Clients do not normally need to worry about this field; the CHRE
764     //! implementation guarantees that the client only receives the structure
765     //! version it expects.
766     uint8_t version;
767 
768     //! The number of ranging results included in the results array; matches the
769     //! number of MAC addresses specified in the request
770     uint8_t resultCount;
771 
772     //! Reserved; set to 0
773     uint8_t reserved[2];
774 
775     //! Pointer to an array containing resultCount entries
776     const struct chreWifiRangingResult *results;
777 };
778 
779 
780 /**
781  * Retrieves a set of flags indicating the WiFi features supported by the
782  * current CHRE implementation. The value returned by this function must be
783  * consistent for the entire duration of the Nanoapp's execution.
784  *
785  * The client must allow for more flags to be set in this response than it knows
786  * about, for example if the implementation supports a newer version of the API
787  * than the client was compiled against.
788  *
789  * @return A bitmask with zero or more CHRE_WIFI_CAPABILITIES_* flags set
790  *
791  * @since v1.1
792  */
793 uint32_t chreWifiGetCapabilities(void);
794 
795 /**
796  * Nanoapps must define CHRE_NANOAPP_USES_WIFI somewhere in their build
797  * system (e.g. Makefile) if the nanoapp needs to use the following WiFi APIs.
798  * In addition to allowing access to these APIs, defining this macro will also
799  * ensure CHRE enforces that all host clients this nanoapp talks to have the
800  * required Android permissions needed to listen to WiFi data by adding metadata
801  * to the nanoapp.
802  */
803 #if defined(CHRE_NANOAPP_USES_WIFI) || !defined(CHRE_IS_NANOAPP_BUILD)
804 
805 /**
806  * Manages a client's request to receive the results of WiFi scans performed for
807  * other purposes, for example scans done to maintain connectivity and scans
808  * requested by other clients. The presence of this request has no effect on the
809  * frequency or configuration of the WiFi scans performed - it is purely a
810  * registration by the client to receive the results of scans that would
811  * otherwise occur normally. This should include all available scan results,
812  * including those that are not normally sent to the applications processor,
813  * such as Preferred Network Offload (PNO) scans. Scan results provided because
814  * of this registration must not contain cached results - they are always
815  * expected to contain the fresh results from a recent scan.
816  *
817  * An active scan monitor subscription must persist across temporary conditions
818  * under which no WiFi scans will be performed, for example if WiFi is
819  * completely disabled via user-controlled settings, or if the WiFi system
820  * restarts independently of CHRE. Likewise, a request to enable a scan monitor
821  * subscription must succeed under normal conditions, even in circumstances
822  * where no WiFi scans will be performed. In these cases, the scan monitor
823  * implementation must produce scan results once the temporary condition is
824  * cleared, for example after WiFi is enabled by the user.
825  *
826  * These scan results are delivered to the Nanoapp's handle event callback using
827  * CHRE_EVENT_WIFI_SCAN_RESULT.
828  *
829  * An active scan monitor subscription is not necessary to receive the results
830  * of an on-demand scan request sent via chreWifiRequestScanAsync(), and it does
831  * not result in duplicate delivery of scan results generated from
832  * chreWifiRequestScanAsync().
833  *
834  * If no monitor subscription is active at the time of a request with
835  * enable=false, it is treated as if an active subscription was successfully
836  * ended.
837  *
838  * The result of this request is delivered asynchronously via an event of type
839  * CHRE_EVENT_WIFI_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
840  * for more details.
841  *
842  * @param enable Set to true to enable monitoring scan results, false to
843  *        disable
844  * @param cookie An opaque value that will be included in the chreAsyncResult
845  *        sent in relation to this request.
846  *
847  * @return true if the request was accepted for processing, false otherwise
848  *
849  * @since v1.1
850  * @note Requires WiFi permission
851  */
852 bool chreWifiConfigureScanMonitorAsync(bool enable, const void *cookie);
853 
854 /**
855  * Sends an on-demand request for WiFi scan results. This may trigger a new
856  * scan, or be entirely serviced from cache, depending on the maxScanAgeMs
857  * parameter.
858  *
859  * This resulting status of this request is delivered asynchronously via an
860  * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered
861  * within CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS of the this request. Refer to the
862  * note in {@link #chreAsyncResult} for more details.
863  *
864  * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that
865  * the scan results are ready to be delivered in a subsequent event (or events,
866  * which arrive consecutively without any other scan results in between)
867  * of type CHRE_EVENT_WIFI_SCAN_RESULT.
868  *
869  * WiFi scanning must be disabled if both "WiFi scanning" and "WiFi" settings
870  * are disabled at the Android level. In this case, the CHRE implementation is
871  * expected to return a result with CHRE_ERROR_FUNCTION_DISABLED.
872  *
873  * It is not valid for a client to request a new scan while a result is pending
874  * based on a previous scan request from the same client. In this situation, the
875  * CHRE implementation is expected to return a result with CHRE_ERROR_BUSY.
876  * However, if a scan is currently pending or in progress due to a request from
877  * another client, whether within the CHRE or otherwise, the implementation must
878  * not fail the request for this reason. If the pending scan satisfies the
879  * client's request parameters, then the implementation should use its results
880  * to satisfy the request rather than scheduling a new scan.
881  *
882  * @param params A set of parameters for the scan request. Must not be NULL.
883  * @param cookie An opaque value that will be included in the chreAsyncResult
884  *        sent in relation to this request.
885  *
886  * @return true if the request was accepted for processing, false otherwise
887  *
888  * @since v1.1
889  * @note Requires WiFi permission
890  */
891 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
892                               const void *cookie);
893 
894 /**
895  * Convenience function which calls chreWifiRequestScanAsync() with a default
896  * set of scan parameters.
897  *
898  * @param cookie An opaque value that will be included in the chreAsyncResult
899  *        sent in relation to this request.
900  *
901  * @return true if the request was accepted for processing, false otherwise
902  *
903  * @since v1.1
904  * @note Requires WiFi permission
905  */
chreWifiRequestScanAsyncDefault(const void * cookie)906 static inline bool chreWifiRequestScanAsyncDefault(const void *cookie) {
907     static const struct chreWifiScanParams params = {
908         /*.scanType=*/         CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE,
909         /*.maxScanAgeMs=*/     5000,  // 5 seconds
910         /*.frequencyListLen=*/ 0,
911         /*.frequencyList=*/    NULL,
912         /*.ssidListLen=*/      0,
913         /*.ssidList=*/         NULL,
914         /*.radioChainPref=*/   CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
915         /*.channelSet=*/       CHRE_WIFI_CHANNEL_SET_NON_DFS
916     };
917     return chreWifiRequestScanAsync(&params, cookie);
918 }
919 
920 /**
921  * Issues a request to initiate distance measurements using round-trip time
922  * (RTT), aka Fine Timing Measurement (FTM), to one or more devices identified
923  * by MAC address. Within CHRE, MACs are typically the BSSIDs of scanned APs
924  * that have the CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER flag set.
925  *
926  * This resulting status of this request is delivered asynchronously via an
927  * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered
928  * within CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS of the this request. Refer to the
929  * note in {@link #chreAsyncResult} for more details.
930  *
931  * WiFi RTT ranging must be disabled if any of the following is true:
932  * - Both "WiFi" and "WiFi Scanning" settings are disabled at the Android level.
933  * - The "Location" setting is disabled at the Android level.
934  * In this case, the CHRE implementation is expected to return a result with
935  * CHRE_ERROR_FUNCTION_DISABLED.
936  *
937  * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that
938  * the results of ranging will be delivered in a subsequent event of type
939  * CHRE_EVENT_WIFI_RANGING_RESULT. Note that the CHRE_EVENT_WIFI_ASYNC_RESULT
940  * gives an overall status - for example, it is used to indicate failure if the
941  * entire ranging request was rejected because WiFi is disabled. However, it is
942  * valid for this event to indicate success, but RTT ranging to fail for all
943  * requested devices - for example, they may be out of range. Therefore, it is
944  * also necessary to check the status field in {@link #chreWifiRangingResult}.
945  *
946  * @param params Structure containing the parameters of the scan request,
947  *        including the list of devices to attempt ranging.
948  * @param cookie An opaque value that will be included in the chreAsyncResult
949  *        sent in relation to this request.
950  *
951  * @return true if the request was accepted for processing, false otherwise
952  *
953  * @since v1.2
954  * @note Requires WiFi permission
955  */
956 bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params,
957                                  const void *cookie);
958 
959 /**
960  * Helper function to populate an instance of struct chreWifiRangingTarget with
961  * the contents of a scan result provided in struct chreWifiScanResult.
962  * Populates other parameters that are not directly derived from the scan result
963  * with default values.
964  *
965  * @param scanResult The scan result to parse as input
966  * @param rangingTarget The RTT ranging target to populate as output
967  *
968  * @note Requires WiFi permission
969  */
chreWifiRangingTargetFromScanResult(const struct chreWifiScanResult * scanResult,struct chreWifiRangingTarget * rangingTarget)970 static inline void chreWifiRangingTargetFromScanResult(
971         const struct chreWifiScanResult *scanResult,
972         struct chreWifiRangingTarget *rangingTarget) {
973     memcpy(rangingTarget->macAddress, scanResult->bssid,
974            sizeof(rangingTarget->macAddress));
975     rangingTarget->primaryChannel      = scanResult->primaryChannel;
976     rangingTarget->centerFreqPrimary   = scanResult->centerFreqPrimary;
977     rangingTarget->centerFreqSecondary = scanResult->centerFreqSecondary;
978     rangingTarget->channelWidth        = scanResult->channelWidth;
979 
980     // Note that this is not strictly necessary (CHRE can see which API version
981     // the nanoapp was built against, so it knows to ignore these fields), but
982     // we do it here to keep things nice and tidy
983     memset(rangingTarget->reserved, 0, sizeof(rangingTarget->reserved));
984 }
985 
986 #else  /* defined(CHRE_NANOAPP_USES_WIFI) || !defined(CHRE_IS_NANOAPP_BUILD) */
987 #define CHRE_WIFI_PERM_ERROR_STRING \
988     "CHRE_NANOAPP_USES_WIFI must be defined when building this nanoapp in " \
989     "order to refer to "
990 #define chreWifiConfigureScanMonitorAsync(...) \
991     CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \
992                      "chreWifiConfigureScanMonitorAsync")
993 #define chreWifiRequestScanAsync(...) \
994     CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \
995                      "chreWifiRequestScanAsync")
996 #define chreWifiRequestScanAsyncDefault(...) \
997     CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \
998                      "chreWifiRequestScanAsyncDefault")
999 #define chreWifiRequestRangingAsync(...) \
1000     CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING "chreWifiRequestRangingAsync")
1001 #define chreWifiRangingTargetFromScanResult(...) \
1002     CHRE_BUILD_ERROR(CHRE_WIFI_PERM_ERROR_STRING \
1003                      "chreWifiRangingTargetFromScanResult")
1004 #endif  /* defined(CHRE_NANOAPP_USES_WIFI) || !defined(CHRE_IS_NANOAPP_BUILD) */
1005 
1006 #ifdef __cplusplus
1007 }
1008 #endif
1009 
1010 #endif  /* _CHRE_WIFI_H_ */
1011