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(&params, &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