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