Home | History | Annotate | Download | only in chre
      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 will be delivered in a subsequent event (or events) of type
    793  * CHRE_EVENT_WIFI_SCAN_RESULT.
    794  *
    795  * It is not valid for a client to request a new scan while a result is pending
    796  * based on a previous scan request from the same client. In this situation, the
    797  * CHRE implementation is expected to return a result with CHRE_ERROR_BUSY.
    798  * However, if a scan is currently pending or in progress due to a request from
    799  * another client, whether within the CHRE or otherwise, the implementation must
    800  * not fail the request for this reason. If the pending scan satisfies the
    801  * client's request parameters, then the implementation should use its results
    802  * to satisfy the request rather than scheduling a new scan.
    803  *
    804  * @param params A set of parameters for the scan request. Must not be NULL.
    805  * @param cookie An opaque value that will be included in the chreAsyncResult
    806  *        sent in relation to this request.
    807  *
    808  * @return true if the request was accepted for processing, false otherwise
    809  *
    810  * @since v1.1
    811  */
    812 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
    813                               const void *cookie);
    814 
    815 /**
    816  * Convenience function which calls chreWifiRequestScanAsync() with a default
    817  * set of scan parameters.
    818  *
    819  * @param cookie An opaque value that will be included in the chreAsyncResult
    820  *        sent in relation to this request.
    821  *
    822  * @return true if the request was accepted for processing, false otherwise
    823  *
    824  * @since v1.1
    825  */
    826 static inline bool chreWifiRequestScanAsyncDefault(const void *cookie) {
    827     struct chreWifiScanParams params = {};
    828     params.scanType         = CHRE_WIFI_SCAN_TYPE_ACTIVE;
    829     params.maxScanAgeMs     = 5000;  // 5 seconds
    830     params.frequencyListLen = 0;
    831     params.ssidListLen      = 0;
    832     params.radioChainPref   = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT;
    833     return chreWifiRequestScanAsync(&params, cookie);
    834 }
    835 
    836 /**
    837  * Issues a request to initiate distance measurements using round-trip time
    838  * (RTT), aka Fine Timing Measurement (FTM), to one or more devices identified
    839  * by MAC address. Within CHRE, MACs are typically the BSSIDs of scanned APs
    840  * that have the CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER flag set.
    841  *
    842  * This resulting status of this request is delivered asynchronously via an
    843  * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered
    844  * within CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS of the this request. Refer to the
    845  * note in {@link #chreAsyncResult} for more details.
    846  *
    847  * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that
    848  * the results of ranging will be delivered in a subsequent event of type
    849  * CHRE_EVENT_WIFI_RANGING_RESULT. Note that the CHRE_EVENT_WIFI_ASYNC_RESULT
    850  * gives an overall status - for example, it is used to indicate failure if the
    851  * entire ranging request was rejected because WiFi is disabled. However, it is
    852  * valid for this event to indicate success, but RTT ranging to fail for all
    853  * requested devices - for example, they may be out of range. Therefore, it is
    854  * also necessary to check the status field in {@link #chreWifiRangingResult}.
    855  *
    856  * @param params Structure containing the parameters of the scan request,
    857  *        including the list of devices to attempt ranging.
    858  * @param cookie An opaque value that will be included in the chreAsyncResult
    859  *        sent in relation to this request.
    860  *
    861  * @return true if the request was accepted for processing, false otherwise
    862  *
    863  * @since v1.2
    864  */
    865 bool chreWifiRequestRangingAsync(const struct chreWifiRangingParams *params,
    866                                  const void *cookie);
    867 
    868 /**
    869  * Helper function to populate an instance of struct chreWifiRangingTarget with
    870  * the contents of a scan result provided in struct chreWifiScanResult.
    871  * Populates other parameters that are not directly derived from the scan result
    872  * with default values.
    873  *
    874  * @param scanResult The scan result to parse as input
    875  * @param rangingTarget The RTT ranging target to populate as output
    876  */
    877 static inline void chreWifiRangingTargetFromScanResult(
    878         const struct chreWifiScanResult *scanResult,
    879         struct chreWifiRangingTarget *rangingTarget) {
    880     memcpy(rangingTarget->macAddress, scanResult->bssid,
    881            sizeof(rangingTarget->macAddress));
    882     rangingTarget->primaryChannel      = scanResult->primaryChannel;
    883     rangingTarget->centerFreqPrimary   = scanResult->centerFreqPrimary;
    884     rangingTarget->centerFreqSecondary = scanResult->centerFreqSecondary;
    885     rangingTarget->channelWidth        = scanResult->channelWidth;
    886 
    887     // Note that this is not strictly necessary (CHRE can see which API version
    888     // the nanoapp was built against, so it knows to ignore these fields), but
    889     // we do it here to keep things nice and tidy
    890     memset(rangingTarget->reserved, 0, sizeof(rangingTarget->reserved));
    891 }
    892 
    893 
    894 #ifdef __cplusplus
    895 }
    896 #endif
    897 
    898 #endif  /* _CHRE_WIFI_H_ */
    899