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 <stdint.h>
     39 
     40 #ifdef __cplusplus
     41 extern "C" {
     42 #endif
     43 
     44 /**
     45  * The set of flags returned by chreWifiGetCapabilities().
     46  * @defgroup CHRE_WIFI_CAPABILITIES
     47  * @{
     48  */
     49 
     50 //! No WiFi APIs are supported
     51 #define CHRE_WIFI_CAPABILITIES_NONE             UINT32_C(0)
     52 
     53 //! Listening to scan results is supported, as enabled via
     54 //! chreWifiConfigureScanMonitorAsync()
     55 #define CHRE_WIFI_CAPABILITIES_SCAN_MONITORING  UINT32_C(1 << 0)
     56 
     57 //! Requesting WiFi scans on-demand is supported via chreWifiRequestScanAsync()
     58 #define CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN   UINT32_C(1 << 1)
     59 
     60 /** @} */
     61 
     62 /**
     63  * Produce an event ID in the block of IDs reserved for WiFi
     64  * @param offset  Index into WiFi event ID block; valid range [0,15]
     65  */
     66 #define CHRE_WIFI_EVENT_ID(offset)  (CHRE_EVENT_WIFI_FIRST_EVENT + (offset))
     67 
     68 /**
     69  * nanoappHandleEvent argument: struct chreAsyncResult
     70  *
     71  * Communicates the asynchronous result of a request to the WiFi API. The
     72  * requestType field in chreAsyncResult is set to a value from enum
     73  * chreWifiRequestType.
     74  */
     75 #define CHRE_EVENT_WIFI_ASYNC_RESULT  CHRE_WIFI_EVENT_ID(0)
     76 
     77 /**
     78  * nanoappHandleEvent argument: struct chreWifiScanEvent
     79  *
     80  * Provides results of a WiFi scan.
     81  */
     82 #define CHRE_EVENT_WIFI_SCAN_RESULT  CHRE_WIFI_EVENT_ID(1)
     83 
     84 // NOTE: Do not add new events with ID > 15; only values 0-15 are reserved
     85 // (see chre/event.h)
     86 
     87 /**
     88  * The maximum amount of time that is allowed to elapse between a call to
     89  * chreWifiRequestScanAsync() that returns true, and the associated
     90  * CHRE_EVENT_WIFI_ASYNC_RESULT used to indicate whether the scan completed
     91  * successfully or not.
     92  */
     93 #define CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS  (30 * CHRE_NSEC_PER_SEC)
     94 
     95 /**
     96  * The current compatibility version of the chreWifiScanEvent structure,
     97  * including nested structures.
     98  */
     99 #define CHRE_WIFI_SCAN_EVENT_VERSION  UINT8_C(1)
    100 
    101 /**
    102  * Maximum number of frequencies that can be explicitly specified when
    103  * requesting a scan
    104  * @see #chreWifiScanParams
    105  */
    106 #define CHRE_WIFI_FREQUENCY_LIST_MAX_LEN  (20)
    107 
    108 /**
    109  * Maximum number of SSIDs that can be explicitly specified when requesting a
    110  * scan
    111  * @see #chreWifiScanParams
    112  */
    113 #define CHRE_WIFI_SSID_LIST_MAX_LEN  (20)
    114 
    115 /**
    116  * The maximum number of octets in an SSID (see 802.11 7.3.2.1)
    117  */
    118 #define CHRE_WIFI_SSID_MAX_LEN  (32)
    119 
    120 /**
    121  * The number of octets in a BSSID (see 802.11 7.1.3.3.3)
    122  */
    123 #define CHRE_WIFI_BSSID_LEN  (6)
    124 
    125 /**
    126  * Set of flags which can either indicate a frequency band. Specified as a bit
    127  * mask to allow for combinations in future API versions.
    128  * @defgroup CHRE_WIFI_BAND_MASK
    129  * @{
    130  */
    131 
    132 #define CHRE_WIFI_BAND_MASK_2_4_GHZ  UINT8_C(1 << 0)  //!< 2.4 GHz
    133 #define CHRE_WIFI_BAND_MASK_5_GHZ    UINT8_C(1 << 1)  //!< 5 GHz
    134 
    135 /** @} */
    136 
    137 /**
    138  * Characteristics of a scanned device given in struct chreWifiScanResult.flags
    139  * @defgroup CHRE_WIFI_SCAN_RESULT_FLAGS
    140  * @{
    141  */
    142 
    143 #define CHRE_WIFI_SCAN_RESULT_FLAGS_NONE                         UINT8_C(0)
    144 
    145 //! Element ID 61 (HT Operation) is present (see HT 7.3.2)
    146 #define CHRE_WIFI_SCAN_RESULT_FLAGS_HT_OPS_PRESENT               UINT8_C(1 << 0)
    147 
    148 //! Element ID 192 (VHT Operation) is present (see VHT 8.4.2)
    149 #define CHRE_WIFI_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT              UINT8_C(1 << 1)
    150 
    151 //! Element ID 127 (Extended Capbilities) is present, and bit 70 (Fine Timing
    152 //! Measurement Responder) is set to 1 (see IEEE draft 802.11mc 8.4.2.26)
    153 #define CHRE_WIFI_SCAN_RESULT_FLAGS_IS_80211MC_RTT_RESPONDER     UINT8_C(1 << 2)
    154 
    155 //! HT Operation element indicates that a secondary channel is present
    156 //! (see HT 7.3.2.57)
    157 #define CHRE_WIFI_SCAN_RESULT_FLAGS_HAS_SECONDARY_CHANNEL_OFFSET UINT8_C(1 << 3)
    158 
    159 //! HT Operation element indicates that the secondary channel is below the
    160 //! primary channel (see HT 7.3.2.57)
    161 #define CHRE_WIFI_SCAN_RESULT_FLAGS_SECONDARY_CHANNEL_OFFSET_IS_BELOW  \
    162                                                                  UINT8_C(1 << 4)
    163 
    164 /** @} */
    165 
    166 /**
    167  * Identifies the authentication methods supported by an AP. Note that not every
    168  * combination of flags may be possible. Based on WIFI_PNO_AUTH_CODE_* from
    169  * hardware/libhardware_legacy/include/hardware_legacy/gscan.h in Android.
    170  * @defgroup CHRE_WIFI_SECURITY_MODE_FLAGS
    171  * @{
    172  */
    173 
    174 #define CHRE_WIFI_SECURITY_MODE_UNKONWN  UINT8_C(0)
    175 
    176 #define CHRE_WIFI_SECURITY_MODE_OPEN  UINT8_C(1 << 0)  //!< No auth/security
    177 #define CHRE_WIFI_SECURITY_MODE_WEP   UINT8_C(1 << 1)
    178 #define CHRE_WIFI_SECURITY_MODE_PSK   UINT8_C(1 << 2)  //!< WPA-PSK or WPA2-PSK
    179 #define CHRE_WIFI_SECURITY_MODE_EAP   UINT8_C(1 << 3)  //!< Any type of EAPOL
    180 
    181 /** @} */
    182 
    183 /**
    184  * Identifies a WiFi frequency band
    185  */
    186 enum chreWifiBand {
    187     CHRE_WIFI_BAND_2_4_GHZ = CHRE_WIFI_BAND_MASK_2_4_GHZ,
    188     CHRE_WIFI_BAND_5_GHZ   = CHRE_WIFI_BAND_MASK_5_GHZ,
    189 };
    190 
    191 /**
    192  * Indicates the BSS operating channel width determined from the VHT and/or HT
    193  * Operation elements. Refer to VHT 8.4.2.161 and HT 7.3.2.57.
    194  */
    195 enum chreWifiChannelWidth {
    196     CHRE_WIFI_CHANNEL_WIDTH_20_MHZ         = 0,
    197     CHRE_WIFI_CHANNEL_WIDTH_40_MHZ         = 1,
    198     CHRE_WIFI_CHANNEL_WIDTH_80_MHZ         = 2,
    199     CHRE_WIFI_CHANNEL_WIDTH_160_MHZ        = 3,
    200     CHRE_WIFI_CHANNEL_WIDTH_80_PLUS_80_MHZ = 4,
    201 };
    202 
    203 /**
    204  * Indicates the type of scan requested or performed
    205  */
    206 enum chreWifiScanType {
    207     //! Perform a purely active scan using probe requests. Do not scan channels
    208     //! restricted to use via Dynamic Frequency Selection (DFS) only.
    209     CHRE_WIFI_SCAN_TYPE_ACTIVE = 0,
    210 
    211     //! Perform an active scan on unrestricted channels, and also perform a
    212     //! passive scan on channels that are restricted to use via Dynamic
    213     //! Frequency Selection (DFS), e.g. the U-NIII bands 5250-5350MHz and
    214     //! 5470-5725MHz in the USA as mandated by FCC regulation.
    215     CHRE_WIFI_SCAN_TYPE_ACTIVE_PLUS_PASSIVE_DFS = 1,
    216 
    217     //! Perform a passive scan, only listening for beacons.
    218     CHRE_WIFI_SCAN_TYPE_PASSIVE = 2,
    219 };
    220 
    221 /**
    222  * Indicates a type of request made in this API. Used to populate the resultType
    223  * field of struct chreAsyncResult sent with CHRE_EVENT_WIFI_ASYNC_RESULT.
    224  */
    225 enum chreWifiRequestType {
    226     CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR = 1,
    227     CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN           = 2,
    228 };
    229 
    230 /**
    231  * SSID with an explicit length field, used when an array of SSIDs is supplied.
    232  */
    233 struct chreWifiSsidListItem {
    234     //! Number of valid bytes in ssid. Valid range [0, CHRE_WIFI_SSID_MAX_LEN]
    235     uint8_t ssidLen;
    236 
    237     //! Service Set Identifier (SSID)
    238     uint8_t ssid[CHRE_WIFI_SSID_MAX_LEN];
    239 };
    240 
    241 /**
    242  * Data structure passed to chreWifiRequestScanAsync
    243  */
    244 struct chreWifiScanParams {
    245     //! Set to a value from enum chreWifiScanType
    246     uint8_t scanType;
    247 
    248     //! Indicates whether the client is willing to tolerate receiving cached
    249     //! results of a previous scan, and if so, the maximum age of the scan that
    250     //! the client will accept. "Age" in this case is defined as the elapsed
    251     //! time between when the most recent scan was completed and the request is
    252     //! received, in milliseconds. If set to 0, no cached results may be
    253     //! provided, and all scan results must come from a "fresh" WiFi scan, i.e.
    254     //! one that completes strictly after this request is received. If more than
    255     //! one scan is cached and meets this age threshold, only the newest scan is
    256     //! provided.
    257     uint32_t maxScanAgeMs;
    258 
    259     //! If set to 0, scan all frequencies. Otherwise, this indicates the number
    260     //! of frequencies to scan, as specified in the frequencyList array. Valid
    261     //! range [0, CHRE_WIFI_FREQUENCY_LIST_MAX_LEN].
    262     uint16_t frequencyListLen;
    263 
    264     //! Pointer to an array of frequencies to scan, given as channel center
    265     //! frequencies in MHz. This field may be NULL if frequencyListLen is 0.
    266     const uint32_t *frequencyList;
    267 
    268     //! If set to 0, do not restrict scan to any SSIDs. Otherwise, this
    269     //! indicates the number of SSIDs in the ssidList array to be used for
    270     //! directed probe requests. Not applicable and ignore when scanType is
    271     //! CHRE_WIFI_SCAN_TYPE_PASSIVE.
    272     uint8_t ssidListLen;
    273 
    274     //! Pointer to an array of SSIDs to use for directed probe requests. May be
    275     //! NULL if ssidListLen is 0.
    276     const struct chreWifiSsidListItem *ssidList;
    277 };
    278 
    279 /**
    280  * Provides information about a single access point (AP) detected in a scan.
    281  */
    282 struct chreWifiScanResult {
    283     //! Number of milliseconds prior to referenceTime in the enclosing
    284     //! chreWifiScanEvent struct when the probe response or beacon frame that
    285     //! was used to populate this structure was received.
    286     uint32_t ageMs;
    287 
    288     //! Capability Information field sent by the AP (see 802.11 7.3.1.4). This
    289     //! field must reflect native byte order and bit ordering, such that
    290     //! (capabilityInfo & 1) gives the bit for the ESS subfield.
    291     uint16_t capabilityInfo;
    292 
    293     //! Number of valid bytes in ssid. Valid range [0, CHRE_WIFI_SSID_MAX_LEN]
    294     uint8_t ssidLen;
    295 
    296     //! Service Set Identifier (SSID), a series of 0 to 32 octets identifying
    297     //! the access point. Note that this is commonly a human-readable ASCII
    298     //! string, but this is not the required encoding per the standard.
    299     uint8_t ssid[CHRE_WIFI_SSID_MAX_LEN];
    300 
    301     //! Basic Service Set Identifier (BSSID), represented in big-endian byte
    302     //! order, such that the first octet of the OUI is accessed in byte index 0.
    303     uint8_t bssid[CHRE_WIFI_BSSID_LEN];
    304 
    305     //! A set of flags from CHRE_WIFI_SCAN_RESULT_FLAGS_*
    306     uint8_t flags;
    307 
    308     //! RSSI (Received Signal Strength Indicator), in dBm. Typically negative.
    309     int8_t  rssi;
    310 
    311     //! Operating band, set to a value from enum chreWifiBand
    312     uint8_t band;
    313 
    314     /**
    315      * Indicates the center frequency of the primary 20MHz channel, given in
    316      * MHz. This value is derived from the channel number via the formula:
    317      *
    318      *     primaryChannel (MHz) = CSF + 5 * primaryChannelNumber
    319      *
    320      * Where CSF is the channel starting frequency (in MHz) given by the
    321      * operating class/band (i.e. 2407 or 5000), and primaryChannelNumber is the
    322      * channel number in the range [1, 200].
    323      *
    324      * Refer to VHT 22.3.14.
    325      */
    326     uint32_t primaryChannel;
    327 
    328     /**
    329      * If the channel width is 20 MHz, this field is not relevant and set to 0.
    330      * If the channel width is 40, 80, or 160 MHz, then this denotes the channel
    331      * center frequency (in MHz). If the channel is 80+80 MHz, then this denotes
    332      * the center frequency of segment 0, which contains the primary channel.
    333      * This value is derived from the frequency index using the same formula as
    334      * for primaryChannel.
    335      *
    336      * Refer to VHT 8.4.2.161, and VHT 22.3.14.
    337      *
    338      * @see #primaryChannel
    339      */
    340     uint32_t centerFreqPrimary;
    341 
    342     /**
    343      * If the channel width is 80+80MHz, then this denotes the center frequency
    344      * of segment 1, which does not contain the primary channel. Otherwise, this
    345      * field is not relevant and set to 0.
    346      *
    347      * @see #centerFreqPrimary
    348      */
    349     uint32_t centerFreqSecondary;
    350 
    351     //! @see #chreWifiChannelWidth
    352     uint8_t channelWidth;
    353 
    354     //! Flags from CHRE_WIFI_SECURITY_MODE_* indicating supported authentication
    355     //! and associated security modes
    356     //! @see CHRE_WIFI_SECURITY_MODE_FLAGS
    357     uint8_t securityMode;
    358 
    359     //! Reserved; set to 0
    360     uint8_t reserved[10];
    361 };
    362 
    363 /**
    364  * Data structure sent with events of type CHRE_EVENT_WIFI_SCAN_RESULT.
    365  */
    366 struct chreWifiScanEvent {
    367     //! Indicates the version of the structure, for compatibility purposes.
    368     //! Clients do not normally need to worry about this field; the CHRE
    369     //! implementation guarantees that the client only receives the structure
    370     //! version it expects.
    371     uint8_t version;
    372 
    373     //! The number of entries in the results array in this event. The CHRE
    374     //! implementation may split scan results across multiple events for memory
    375     //! concerns, etc.
    376     uint8_t resultCount;
    377 
    378     //! The total number of results returned by the scan. Allows an event
    379     //! consumer to identify when it has received all events associated with a
    380     //! scan.
    381     uint8_t resultTotal;
    382 
    383     //! Sequence number for this event within the series of events comprising a
    384     //! complete scan result. Scan events are delivered strictly in order, i.e.
    385     //! this is monotonically increasing for the results of a single scan. Valid
    386     //! range [0, <number of events for scan> - 1]. The number of events for a
    387     //! scan is typically given by
    388     //! ceil(resultTotal / <max results per event supported by platform>).
    389     uint8_t eventIndex;
    390 
    391     //! A value from enum chreWifiScanType indicating the type of scan performed
    392     uint8_t scanType;
    393 
    394     //! If a directed scan was performed to a limited set of SSIDs, then this
    395     //! identifies the number of unique SSIDs included in the probe requests.
    396     //! Otherwise, this is set to 0, indicating that the scan was not limited by
    397     //! SSID. Note that if this is non-zero, the list of SSIDs used is not
    398     //! included in the scan event.
    399     uint8_t ssidSetSize;
    400 
    401     //! If 0, indicates that all frequencies applicable for the scanType were
    402     //! scanned. Otherwise, indicates the number of frequencies scanned, as
    403     //! specified in scannedFreqList.
    404     uint16_t scannedFreqListLen;
    405 
    406     //! Timestamp when the scan was completed, from the same time base as
    407     //! chreGetTime() (in nanoseconds)
    408     uint64_t referenceTime;
    409 
    410     //! Pointer to an array containing scannedFreqListLen values comprising the
    411     //! set of frequencies that were scanned. Frequencies are specified as
    412     //! channel center frequencies in MHz. May be NULL if scannedFreqListLen is
    413     //! 0.
    414     const uint32_t *scannedFreqList;
    415 
    416     //! Pointer to an array containing resultCount entries. May be NULL if
    417     //! resultCount is 0.
    418     const struct chreWifiScanResult *results;
    419 };
    420 
    421 /**
    422  * Retrieves a set of flags indicating the WiFi features supported by the
    423  * current CHRE implementation. The value returned by this function must be
    424  * consistent for the entire duration of the Nanoapp's execution.
    425  *
    426  * The client must allow for more flags to be set in this response than it knows
    427  * about, for example if the implementation supports a newer version of the API
    428  * than the client was compiled against.
    429  *
    430  * @return A bitmask with zero or more CHRE_WIFI_CAPABILITIES_* flags set
    431  *
    432  * @since v1.1
    433  */
    434 uint32_t chreWifiGetCapabilities(void);
    435 
    436 /**
    437  * Manages a client's request to receive the results of WiFi scans performed for
    438  * other purposes, for example scans done to maintain connectivity and scans
    439  * requested by other clients. The presence of this request has no effect on the
    440  * frequency or configuration of the WiFi scans performed - it is purely a
    441  * registration by the client to receive the results of scans that would
    442  * otherwise occur normally. This should include all available scan results,
    443  * including those that are not normally sent to the applications processor,
    444  * such as Preferred Network Offload (PNO) scans. Scan results provided because
    445  * of this registration must not contain cached results - they are always
    446  * expected to contain the fresh results from a recent scan.
    447  *
    448  * These scan results are delivered to the Nanoapp's handle event callback using
    449  * CHRE_EVENT_WIFI_SCAN_RESULT.
    450  *
    451  * An active scan monitor subscription is not necessary to receive the results
    452  * of an on-demand scan request sent via chreWifiRequestScanAsync().
    453  *
    454  * This result of this request is delivered asynchronously via an event of type
    455  * CHRE_EVENT_WIFI_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
    456  * for more details.
    457  *
    458  * @param enable Set to true to enable monitoring scan results, false to
    459  *        disable
    460  * @param cookie An opaque value that will be included in the chreAsyncResult
    461  *        sent in relation to this request.
    462  *
    463  * @return true if the request was accepted for processing, false otherwise
    464  *
    465  * @since v1.1
    466  */
    467 bool chreWifiConfigureScanMonitorAsync(bool enable, const void *cookie);
    468 
    469 /**
    470  * Sends an on-demand request for WiFi scan results. This may trigger a new
    471  * scan, or be entirely serviced from cache, depending on the maxScanAgeMs
    472  * parameter.
    473  *
    474  * This resulting status of this request is delivered asynchronously via an
    475  * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered
    476  * within CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS of the this request. Refer to the
    477  * note in {@link #chreAsyncResult} for more details.
    478  *
    479  * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that
    480  * the scan results will be delivered in a subsequent event (or events) of type
    481  * CHRE_EVENT_WIFI_SCAN_RESULT.
    482  *
    483  * It is not valid for a client to request a new scan while a result is pending
    484  * based on a previous scan request from the same client. In this situation, the
    485  * CHRE implementation is expected to return a result with CHRE_ERROR_BUSY.
    486  * However, if a scan is currently pending or in progress due to a request from
    487  * another client, whether within the CHRE or otherwise, the implementation must
    488  * not fail the request for this reason. If the pending scan satisfies the
    489  * client's request parameters, then the implementation should use its results
    490  * to satisfy the request rather than scheduling a new scan.
    491  *
    492  * @param params A set of parameters for the scan request. Must not be NULL.
    493  * @param cookie An opaque value that will be included in the chreAsyncResult
    494  *        sent in relation to this request.
    495  *
    496  * @return true if the request was accepted for processing, false otherwise
    497  *
    498  * @since v1.1
    499  */
    500 bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
    501                               const void *cookie);
    502 
    503 /**
    504  * Convenience function which calls chreWifiRequestScanAsync() with a default
    505  * set of scan parameters.
    506  *
    507  * @param cookie An opaque value that will be included in the chreAsyncResult
    508  *        sent in relation to this request.
    509  *
    510  * @return true if the request was accepted for processing, false otherwise
    511  *
    512  * @since v1.1
    513  */
    514 inline bool chreWifiRequestScanAsyncDefault(const void *cookie) {
    515     struct chreWifiScanParams params = {};
    516     params.scanType         = CHRE_WIFI_SCAN_TYPE_ACTIVE;
    517     params.maxScanAgeMs     = 5000;  // 5 seconds
    518     params.frequencyListLen = 0;
    519     params.ssidListLen      = 0;
    520     return chreWifiRequestScanAsync(&params, cookie);
    521 }
    522 
    523 #ifdef __cplusplus
    524 }
    525 #endif
    526 
    527 #endif  /* _CHRE_WIFI_H_ */
    528