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(¶ms, 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