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