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(¶ms, cookie); 521 } 522 523 #ifdef __cplusplus 524 } 525 #endif 526 527 #endif /* _CHRE_WIFI_H_ */ 528