109f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol/* 209f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * Copyright (C) 2017 The Android Open Source Project 309f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * 409f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * Licensed under the Apache License, Version 2.0 (the "License"); 509f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * you may not use this file except in compliance with the License. 609f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * You may obtain a copy of the License at 709f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * 809f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * http://www.apache.org/licenses/LICENSE-2.0 909f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * 1009f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * Unless required by applicable law or agreed to in writing, software 1109f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * distributed under the License is distributed on an "AS IS" BASIS, 1209f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1309f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * See the License for the specific language governing permissions and 1409f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol * limitations under the License. 1509f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol */ 1609f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 17a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#include <chre.h> 1809f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol#include <cinttypes> 1909f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 20a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#include "chre/util/nanoapp/log.h" 211ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol#include "chre/util/time.h" 22da6eaabf8572a16acaebd516dd96ce0063d71e91Andrew Rossignol#include "chre/util/nanoapp/wifi.h" 23a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol 24a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol#define LOG_TAG "[WifiWorld]" 2509f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 261ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol//#define WIFI_WORLD_VERBOSE_WIFI_RESULT_LOGS 271ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol 28e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#ifdef CHRE_NANOAPP_INTERNAL 2909f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignolnamespace chre { 30e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolnamespace { 31e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#endif // CHRE_NANOAPP_INTERNAL 3209f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 331587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol//! A dummy cookie to pass into the configure scan monitoring async request. 341587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignolconst uint32_t kScanMonitoringCookie = 0x1337; 351587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 361ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol//! A dummy cookie to pass into request scan async. 371ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignolconst uint32_t kOnDemandScanCookie = 0xcafe; 381ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol 391ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol//! The interval for on-demand wifi scans. 401ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignolconst Nanoseconds kWifiScanInterval = Nanoseconds(Seconds(10)); 411ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol 421ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol//! A handle for the cyclic timer to request periodic on-demand wifi-scans. 431ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignoluint32_t gWifiScanTimerHandle; 441ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol 4504766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol//! A global instance of wifi capabilities to use when reqeuesting wifi 4604766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol//! functionality. This is populated at startup. 4704766b8b672730f55ab9678697bfeb732912207eAndrew Rossignoluint32_t gWifiCapabilities; 4804766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol 491587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignolnamespace { 501587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 511587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol/** 52de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol * Logs a CHRE wifi scan result. 53de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol * 54de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol * @param result the scan result to log. 55de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol */ 56de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignolvoid logChreWifiResult(const chreWifiScanResult& result) { 57de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol const char *ssidStr = "<non-printable>"; 58de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol char ssidBuffer[kMaxSsidStrLen]; 59de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol if (result.ssidLen == 0) { 60de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol ssidStr = "<empty>"; 61de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol } else if (parseSsidToStr(ssidBuffer, kMaxSsidStrLen, 62de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol result.ssid, result.ssidLen)) { 63de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol ssidStr = ssidBuffer; 64de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol } 65de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol 66de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol const char *bssidStr = "<non-printable>"; 67de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol char bssidBuffer[kBssidStrLen]; 68de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol if (parseBssidToStr(result.bssid, bssidBuffer, kBssidStrLen)) { 69de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol bssidStr = bssidBuffer; 70de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol } 71de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol 72de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI("Found network with SSID: %s", ssidStr); 731ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol#ifdef WIFI_WORLD_VERBOSE_WIFI_RESULT_LOGS 74de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" age (ms): %" PRIu32, result.ageMs); 75de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" capability info: %" PRIx16, result.capabilityInfo); 76de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" bssid: %s", bssidStr); 77de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" flags: %" PRIx8, result.flags); 78de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" rssi: %" PRId8 "dBm", result.rssi); 79de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" band: %s (%" PRIu8 ")", parseChreWifiBand(result.band), result.band); 80de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" primary channel: %" PRIu32, result.primaryChannel); 81de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" center frequency primary: %" PRIu32, result.centerFreqPrimary); 82de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" center frequency secondary: %" PRIu32, result.centerFreqSecondary); 83de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" channel width: %" PRIu8, result.channelWidth); 84de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol LOGI(" security mode: %" PRIx8, result.securityMode); 851ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol#endif // WIFI_WORLD_VERBOSE_WIFI_RESULT_LOGS 86de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol} 87de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol 88de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol/** 8904766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol * Requests a delayed wifi scan using a one-shot timer. The interval is 9004766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol * specified as a constant at the top of this file. 9104766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol */ 9204766b8b672730f55ab9678697bfeb732912207eAndrew Rossignolvoid requestDelayedWifiScan() { 9304766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol if (gWifiCapabilities & CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN) { 9404766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol // Schedule a timer to send an active wifi scan. 9504766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiScanTimerHandle = chreTimerSet(kWifiScanInterval.toRawNanoseconds(), 9604766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol &gWifiScanTimerHandle /* data */, 9704766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol true /* oneShot */); 9804766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol if (gWifiScanTimerHandle == CHRE_TIMER_INVALID) { 9904766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol LOGE("Failed to set timer for delayed wifi scan"); 10004766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol } else { 10104766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol LOGI("Set a timer to request a WiFi scan"); 10204766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol } 10304766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol } 10404766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol} 10504766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol 10604766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol/** 1071587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * Handles the result of an asynchronous request for a wifi resource. 1081587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * 1091587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * @param result a pointer to the event structure containing the result of the 1101587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * request. 1111587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol */ 1121587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignolvoid handleWifiAsyncResult(const chreAsyncResult *result) { 1131587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol if (result->requestType == CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR) { 1141587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol if (result->success) { 115a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Successfully requested wifi scan monitoring"); 1161587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } else { 117463f8eef80b7e33bf795f35657b5a61cd0607407Andrew Rossignol LOGE("Error requesting wifi scan monitoring with %" PRIu8, 118a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol result->errorCode); 1191587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } 1201587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 1211587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol if (result->cookie != &kScanMonitoringCookie) { 122a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGE("Scan monitoring request cookie mismatch"); 1231587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } 1241ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } else if (result->requestType == CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN) { 1251ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol if (result->success) { 1261ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol LOGI("Successfully requested an on-demand wifi scan"); 1271ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } else { 1281ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol LOGE("Error requesting an on-demand wifi scan with %" PRIu8, 1291ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol result->errorCode); 1301ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } 1311ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol 1321ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol if (result->cookie != &kOnDemandScanCookie) { 1331ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol LOGE("On-demand scan cookie mismatch"); 1341ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } 13504766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol 13604766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol requestDelayedWifiScan(); 137463f8eef80b7e33bf795f35657b5a61cd0607407Andrew Rossignol } else { 138463f8eef80b7e33bf795f35657b5a61cd0607407Andrew Rossignol LOGE("Received invalid async result"); 1391587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } 1401587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol} 1411587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 1421587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol/** 1431587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * Handles a wifi scan event. 1441587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * 1451587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol * @param event a pointer to the details of the wifi scan event. 1461587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol */ 1471587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignolvoid handleWifiScanEvent(const chreWifiScanEvent *event) { 1480c064ae46b56433bfcd5072a388423aec86430f7Andrew Rossignol LOGI("Received Wifi scan event with %" PRIu8 " results at %" PRIu64 "ns", 1490c064ae46b56433bfcd5072a388423aec86430f7Andrew Rossignol event->resultCount, event->referenceTime); 150bc573e2ce214e0a8982ebfc34b39a12fdfd61904Andrew Rossignol 151da6eaabf8572a16acaebd516dd96ce0063d71e91Andrew Rossignol for (uint8_t i = 0; i < event->resultCount; i++) { 152da6eaabf8572a16acaebd516dd96ce0063d71e91Andrew Rossignol const chreWifiScanResult& result = event->results[i]; 153de21e14b333cc8f52db1e759b537c4c1a8e81dd3Andrew Rossignol logChreWifiResult(result); 154da6eaabf8572a16acaebd516dd96ce0063d71e91Andrew Rossignol } 1551587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol} 1561587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 1571ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol/** 1581ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol * Handles a timer event. 1591ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol * 1601ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol * @param eventData The cookie passed to the timer request. 1611ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol */ 1621ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignolvoid handleTimerEvent(const void *eventData) { 1631ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol const uint32_t *timerHandle = static_cast<const uint32_t *>(eventData); 1641ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol if (*timerHandle == gWifiScanTimerHandle) { 16570ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol struct chreWifiScanParams params = {}; 16670ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol params.scanType = CHRE_WIFI_SCAN_TYPE_ACTIVE; 16770ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol params.maxScanAgeMs = 5000; // 5 seconds 16870ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol params.frequencyListLen = 0; 16970ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol params.ssidListLen = 0; 17070ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol 17170ba5d5359b9fdb0578cc247f6faacb295534339Andrew Rossignol if (chreWifiRequestScanAsync(¶ms, &kOnDemandScanCookie)) { 1721ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol LOGI("Requested a wifi scan successfully"); 1731ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } else { 1741ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol LOGE("Failed to request a wifi scan"); 1751ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } 1761ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } else { 1771ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol LOGE("Received invalid timer handle"); 1781ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol } 1791ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol} 1801ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol 1811587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol} // namespace 1821587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 183e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolbool nanoappStart() { 184a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("App started as instance %" PRIu32, chreGetInstanceId()); 18509f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 18604766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol const char *gWifiCapabilitiesStr; 18704766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilities = chreWifiGetCapabilities(); 18804766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol switch (gWifiCapabilities) { 18909f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol case CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN 19009f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol | CHRE_WIFI_CAPABILITIES_SCAN_MONITORING: 19104766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilitiesStr = "ON_DEMAND_SCAN | SCAN_MONITORING"; 19209f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol break; 19309f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol case CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN: 19404766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilitiesStr = "ON_DEMAND_SCAN"; 19509f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol break; 19609f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol case CHRE_WIFI_CAPABILITIES_SCAN_MONITORING: 19704766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilitiesStr = "SCAN_MONITORING"; 19809f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol break; 19909f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol case CHRE_WIFI_CAPABILITIES_NONE: 20004766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilitiesStr = "NONE"; 20109f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol break; 20209f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol default: 20304766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilitiesStr = "INVALID"; 20409f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol } 20509f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 206a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Detected WiFi support as: %s (%" PRIu32 ")", 20704766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol gWifiCapabilitiesStr, gWifiCapabilities); 2081587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 20904766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol if (gWifiCapabilities & CHRE_WIFI_CAPABILITIES_SCAN_MONITORING) { 2101587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol if (chreWifiConfigureScanMonitorAsync(true, &kScanMonitoringCookie)) { 211a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Scan monitor enable request successful"); 2121587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } else { 213a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGE("Error sending scan monitoring request"); 2141587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } 2151587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } 2161587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol 21704766b8b672730f55ab9678697bfeb732912207eAndrew Rossignol requestDelayedWifiScan(); 21809f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol return true; 21909f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol} 22009f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 221e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignolvoid nanoappHandleEvent(uint32_t senderInstanceId, 222e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol uint16_t eventType, 223e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol const void *eventData) { 2241587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol switch (eventType) { 2251587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol case CHRE_EVENT_WIFI_ASYNC_RESULT: 2261587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol handleWifiAsyncResult(static_cast<const chreAsyncResult *>(eventData)); 2271587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol break; 2281587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol case CHRE_EVENT_WIFI_SCAN_RESULT: 2291587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol handleWifiScanEvent(static_cast<const chreWifiScanEvent *>(eventData)); 2301587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol break; 2311ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol case CHRE_EVENT_TIMER: 2321ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol handleTimerEvent(eventData); 2331ac1f606166ed611241d3605df45fcbbeceb022dAndrew Rossignol break; 2341587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol default: 235a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGW("Unhandled event type %" PRIu16, eventType); 2361587af4ff0a6574d626c6e2d392173d151a23720Andrew Rossignol } 23709f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol} 23809f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 2392b9d71a9f6a9e8cc0e787957d022154231f29962Brian Duddievoid nanoappEnd() { 240a16406ba1a734f21f36a4b0f64b23b062644b6e2Andrew Rossignol LOGI("Wifi world app stopped"); 24109f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol} 24209f699fd649d1a1db49dc7317549729cea4356afAndrew Rossignol 243e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#ifdef CHRE_NANOAPP_INTERNAL 2449d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} // anonymous namespace 2459d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} // namespace chre 246e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 2479d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie#include "chre/util/nanoapp/app_id.h" 2489d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie#include "chre/platform/static_nanoapp_init.h" 249e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol 2509d5b500a223ef73560f0dce38f50b809bde5dd0dBrian DuddieCHRE_STATIC_NANOAPP_INIT(WifiWorld, chre::kWifiWorldAppId, 0); 251e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol#endif // CHRE_NANOAPP_INTERNAL 252