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
41extern "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 */
186enum 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 */
195enum 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 */
206enum 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 */
225enum 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 */
233struct 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 */
244struct 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 */
282struct 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 */
366struct 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 */
434uint32_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 * An active scan monitor subscription must persist across temporary conditions
449 * under which no WiFi scans will be performed, for example if WiFi is
450 * completely disabled via user-controlled settings, or if the WiFi system
451 * restarts independently of CHRE. Likewise, a request to enable a scan monitor
452 * subscription must succeed under normal conditions, even in circumstances
453 * where no WiFi scans will be performed. In these cases, the scan monitor
454 * implementation must produce scan results once the temporary condition is
455 * cleared, for example after WiFi is enabled by the user.
456 *
457 * These scan results are delivered to the Nanoapp's handle event callback using
458 * CHRE_EVENT_WIFI_SCAN_RESULT.
459 *
460 * An active scan monitor subscription is not necessary to receive the results
461 * of an on-demand scan request sent via chreWifiRequestScanAsync().
462 *
463 * This result of this request is delivered asynchronously via an event of type
464 * CHRE_EVENT_WIFI_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
465 * for more details.
466 *
467 * @param enable Set to true to enable monitoring scan results, false to
468 *        disable
469 * @param cookie An opaque value that will be included in the chreAsyncResult
470 *        sent in relation to this request.
471 *
472 * @return true if the request was accepted for processing, false otherwise
473 *
474 * @since v1.1
475 */
476bool chreWifiConfigureScanMonitorAsync(bool enable, const void *cookie);
477
478/**
479 * Sends an on-demand request for WiFi scan results. This may trigger a new
480 * scan, or be entirely serviced from cache, depending on the maxScanAgeMs
481 * parameter.
482 *
483 * This resulting status of this request is delivered asynchronously via an
484 * event of type CHRE_EVENT_WIFI_ASYNC_RESULT. The result must be delivered
485 * within CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS of the this request. Refer to the
486 * note in {@link #chreAsyncResult} for more details.
487 *
488 * A successful result provided in CHRE_EVENT_WIFI_ASYNC_RESULT indicates that
489 * the scan results will be delivered in a subsequent event (or events) of type
490 * CHRE_EVENT_WIFI_SCAN_RESULT.
491 *
492 * It is not valid for a client to request a new scan while a result is pending
493 * based on a previous scan request from the same client. In this situation, the
494 * CHRE implementation is expected to return a result with CHRE_ERROR_BUSY.
495 * However, if a scan is currently pending or in progress due to a request from
496 * another client, whether within the CHRE or otherwise, the implementation must
497 * not fail the request for this reason. If the pending scan satisfies the
498 * client's request parameters, then the implementation should use its results
499 * to satisfy the request rather than scheduling a new scan.
500 *
501 * @param params A set of parameters for the scan request. Must not be NULL.
502 * @param cookie An opaque value that will be included in the chreAsyncResult
503 *        sent in relation to this request.
504 *
505 * @return true if the request was accepted for processing, false otherwise
506 *
507 * @since v1.1
508 */
509bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params,
510                              const void *cookie);
511
512/**
513 * Convenience function which calls chreWifiRequestScanAsync() with a default
514 * set of scan parameters.
515 *
516 * @param cookie An opaque value that will be included in the chreAsyncResult
517 *        sent in relation to this request.
518 *
519 * @return true if the request was accepted for processing, false otherwise
520 *
521 * @since v1.1
522 */
523inline bool chreWifiRequestScanAsyncDefault(const void *cookie) {
524    struct chreWifiScanParams params = {};
525    params.scanType         = CHRE_WIFI_SCAN_TYPE_ACTIVE;
526    params.maxScanAgeMs     = 5000;  // 5 seconds
527    params.frequencyListLen = 0;
528    params.ssidListLen      = 0;
529    return chreWifiRequestScanAsync(&params, cookie);
530}
531
532#ifdef __cplusplus
533}
534#endif
535
536#endif  /* _CHRE_WIFI_H_ */
537