1cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song/* 2cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Copyright (C) 2017 The Android Open Source Project 3cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * 4cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Portions copyright (C) 2017 Broadcom Limited 5cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * 6cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Licensed under the Apache License, Version 2.0 (the "License"); 7cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * you may not use this file except in compliance with the License. 8cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * You may obtain a copy of the License at 9cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * 10cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * http://www.apache.org/licenses/LICENSE-2.0 11cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * 12cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Unless required by applicable law or agreed to in writing, software 13cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * distributed under the License is distributed on an "AS IS" BASIS, 14cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * See the License for the specific language governing permissions and 16cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * limitations under the License. 17cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song */ 181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <stdint.h> 201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <fcntl.h> 211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <sys/socket.h> 221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/genl.h> 231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/family.h> 241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/ctrl.h> 251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/rtnetlink.h> 261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netpacket/packet.h> 271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/filter.h> 281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/errqueue.h> 291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/pkt_sched.h> 311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/object-api.h> 321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/netlink.h> 331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/socket.h> 34642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande#include <netlink/handlers.h> 351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "sync.h" 371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#define LOG_TAG "WifiHAL" 39de1c9aa3d3ac645f09507d1ff500fc4dc018624dKevin Cernekee//#define LOG_NDEBUG 0 //uncomment to enable verbose logging 401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 41f05bfb019590f8e25471c0fae23db519dfcfb790Pierre Couillaud#include <log/log.h> 421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "wifi_hal.h" 441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "common.h" 451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "cpp_bindings.h" 461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndetypedef enum { 481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, 501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BASE_PERIOD, 51922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde GSCAN_ATTRIBUTE_BUCKETS_BAND, 521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_ID, 531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_PERIOD, 541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, 551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_CHANNELS, 561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, 571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_REPORT_THRESHOLD, 581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, 5927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, 601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, 621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ 631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ 64922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde GSCAN_ENABLE_FULL_SCAN_RESULTS, 65922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde GSCAN_ATTRIBUTE_REPORT_EVENTS, 661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, 691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_FLUSH_RESULTS, 701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ 711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ 721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ 731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ 7427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GSCAN_ATTRIBUTE_NUM_CHANNELS, 7527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GSCAN_ATTRIBUTE_CHANNEL_LIST, 762b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK, 771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SSID = 40, 801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BSSID, 811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_CHANNEL, 821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI, 831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_TIMESTAMP, 841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RTT, 851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RTTSD, 861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, 901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI_LOW, 911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI_HIGH, 921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_HOTLIST_ELEM, 931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 9466d82546960bb2408e1aa31856a3f9a6a400681fInsun Song GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT, 951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, 981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, 991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_MIN_BREACHING, 1001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, 1011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10389a9a4cffbcee6af504c61ff575a008194070c82Ashwin /* EPNO */ 10489a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70, 10589a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_SSID, 10689a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_SSID_LEN, 10789a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_RSSI, 10889a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_FLAGS, 10989a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_AUTH, 11089a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_SSID_NUM, 11189a9a4cffbcee6af504c61ff575a008194070c82Ashwin GSCAN_ATTRIBUTE_EPNO_FLUSH, 11289a9a4cffbcee6af504c61ff575a008194070c82Ashwin 113810c949db9c60baa02684a50d71026727c357cd2Ashwin /* remaining reserved for additional attributes */ 114810c949db9c60baa02684a50d71026727c357cd2Ashwin 115810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_WHITELIST_SSID = 80, 116810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_NUM_WL_SSID, 117810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_WL_SSID_LEN, 118810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_WL_SSID_FLUSH, 119810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM, 120810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_NUM_BSSID, 121810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_BSSID_PREF_LIST, 122810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH, 123810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_BSSID_PREF, 124810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_RSSI_MODIFIER, 125810c949db9c60baa02684a50d71026727c357cd2Ashwin 126810c949db9c60baa02684a50d71026727c357cd2Ashwin /* remaining reserved for additional attributes */ 127810c949db9c60baa02684a50d71026727c357cd2Ashwin 128810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90, 129810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD, 130810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR, 131810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR, 132810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST, 133810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS, 134810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER, 135810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE, 136810c949db9c60baa02684a50d71026727c357cd2Ashwin 137810c949db9c60baa02684a50d71026727c357cd2Ashwin /* BSSID blacklist */ 138810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH = 100, 139810c949db9c60baa02684a50d71026727c357cd2Ashwin GSCAN_ATTRIBUTE_BLACKLIST_BSSID, 140810c949db9c60baa02684a50d71026727c357cd2Ashwin 141f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng /* ANQPO */ 142f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110, 143f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, 144f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, 145f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, 146f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID, 147f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, 148f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 14925a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin /* Adaptive scan attributes */ 15025a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120, 15125a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD, 15225a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin 1532b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin /* ePNO cfg */ 1542b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR = 130, 1552b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR, 1562b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX, 1572b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS, 1582b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS, 1592b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS, 1602b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin GSCAN_ATTRIBUTE_EPNO_5G_BONUS, 1612b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin 1621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_MAX 1631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} GSCAN_ATTRIBUTE; 1651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 166922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 167922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde// helper methods 168922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_enable_full_scan_results(wifi_request_id id, wifi_interface_handle iface, 169922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler); 170922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface); 17177e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwinint wifi_handle_full_scan_event(wifi_request_id id, WifiEvent& event, 17277e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin wifi_scan_result_handler handler); 1732b31c56930bc154d639da4ff2f56c34ef61688e5Ashwinvoid convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from); 1742b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin 1752b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin 1762b31c56930bc154d639da4ff2f56c34ef61688e5Ashwinvoid convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from) 1772b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin{ 1782b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->ts = from->ts; 1792b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->channel = from->channel; 1802b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->rssi = from->rssi; 1812b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->rtt = from->rtt; 1822b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->rtt_sd = from->rtt_sd; 1832b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->beacon_period = from->beacon_period; 1842b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin to->capability = from->capability; 1852b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memcpy(to->ssid, from->ssid, (DOT11_MAX_SSID_LEN+1)); 1862b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memcpy(&to->bssid, &from->bssid, sizeof(mac_addr)); 1872b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin} 188922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 1891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 1901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass GetCapabilitiesCommand : public WifiCommand 1921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_gscan_capabilities *mCapabilities; 1941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 1951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetCapabilitiesCommand(wifi_interface_handle iface, wifi_gscan_capabilities *capabitlites) 196d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("GetGscanCapabilitiesCommand", iface, 0), mCapabilities(capabitlites) 1971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { 1981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(mCapabilities, 0, sizeof(*mCapabilities)); 1991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int create() { 202a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Creating message to get scan capablities; iface = %d", mIfaceInfo->id); 2031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CAPABILITIES); 2051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (ret < 0) { 2061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 2071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 2101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprotected: 2131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 2141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 215a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("In GetCapabilities::handleResponse"); 2161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (reply.get_cmd() != NL80211_CMD_VENDOR) { 2181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 2191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 2201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int id = reply.get_vendor_id(); 2231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int subcmd = reply.get_vendor_subcmd(); 2241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde void *data = reply.get_vendor_data(); 2261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = reply.get_vendor_data_len(); 2271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 228a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len, 229e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande sizeof(*mCapabilities)); 230e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande 231e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities))); 2321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_OK; 2341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 2361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, 2391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_gscan_capabilities *capabilities) 2401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 2411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetCapabilitiesCommand command(handle, capabilities); 2421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return (wifi_error) command.requestResponse(); 2431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 2441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 24527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinclass GetChannelListCommand : public WifiCommand 24627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin{ 24727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin wifi_channel *channels; 24827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int max_channels; 24927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int *num_channels; 25027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int band; 25127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinpublic: 25227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GetChannelListCommand(wifi_interface_handle iface, wifi_channel *channel_buf, int *ch_num, 25327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int num_max_ch, int band) 254d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("GetChannelListCommand", iface, 0), channels(channel_buf), 255d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande max_channels(num_max_ch), num_channels(ch_num), band(band) 25627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin { 25727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin memset(channels, 0, sizeof(wifi_channel) * max_channels); 25827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 25927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin virtual int create() { 260a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Creating message to get channel list; iface = %d", mIfaceInfo->id); 26127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 26227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CHANNEL_LIST); 26327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (ret < 0) { 26427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return ret; 26527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 26627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 26727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); 26827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ret = mMsg.put_u32(GSCAN_ATTRIBUTE_BAND, band); 26927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (ret < 0) { 27027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return ret; 27127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 27227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 27327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin mMsg.attr_end(data); 27427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 27527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return ret; 27627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 27727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 27827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinprotected: 27927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin virtual int handleResponse(WifiEvent& reply) { 28027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 281a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("In GetChannelList::handleResponse"); 28227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 28327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (reply.get_cmd() != NL80211_CMD_VENDOR) { 28427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 28527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return NL_SKIP; 28627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 28727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 28827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int id = reply.get_vendor_id(); 28927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int subcmd = reply.get_vendor_subcmd(); 29027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int num_channels_to_copy = 0; 29127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 29227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 29327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int len = reply.get_vendor_data_len(); 29427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 295a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 29627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (vendor_data == NULL || len == 0) { 29727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGE("no vendor data in GetChannelList response; ignoring it"); 29827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return NL_SKIP; 29927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 30027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 30127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 30227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (it.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS) { 30327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin num_channels_to_copy = it.get_u32(); 30427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGI("Got channel list with %d channels", num_channels_to_copy); 30527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if(num_channels_to_copy > max_channels) 30627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin num_channels_to_copy = max_channels; 30727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin *num_channels = num_channels_to_copy; 30827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } else if (it.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST && num_channels_to_copy) { 30927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin memcpy(channels, it.get_data(), sizeof(int) * num_channels_to_copy); 31027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } else { 31127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGW("Ignoring invalid attribute type = %d, size = %d", 31227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin it.get_type(), it.get_len()); 31327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 31427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 31527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 31627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return NL_OK; 31727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 31827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin}; 31927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 32027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinwifi_error wifi_get_valid_channels(wifi_interface_handle handle, 32127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int band, int max_channels, wifi_channel *channels, int *num_channels) 32227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin{ 32327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GetChannelListCommand command(handle, channels, num_channels, 32427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin max_channels, band); 32527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return (wifi_error) command.requestResponse(); 32627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin} 3271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 3281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/* helper functions */ 3301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int parseScanResults(wifi_scan_result *results, int num, nlattr *attr) 3321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 3331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(results, 0, sizeof(wifi_scan_result) * num); 3341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int i = 0; 3361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it(attr); it.has_next() && i < num; it.next(), i++) { 3371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int index = it.get_type(); 3391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("retrieved scan result %d", index); 3401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *sc_data = (nlattr *) it.get_data(); 3411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result *result = results + i; 3421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it2(sc_data); it2.has_next(); it2.next()) { 3441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int type = it2.get_type(); 3451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (type == GSCAN_ATTRIBUTE_SSID) { 3461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde strncpy(result->ssid, (char *) it2.get_data(), it2.get_len()); 3471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ssid[it2.get_len()] = 0; 3481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_BSSID) { 3491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memcpy(result->bssid, (byte *) it2.get_data(), sizeof(mac_addr)); 3501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_TIMESTAMP) { 3511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ts = it2.get_u64(); 3521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_CHANNEL) { 3531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ts = it2.get_u16(); 3541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_RSSI) { 3551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->rssi = it2.get_u8(); 3561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_RTT) { 3571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->rtt = it2.get_u64(); 3581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_RTTSD) { 3591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->rtt_sd = it2.get_u64(); 3601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (i >= num) { 3661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Got too many results; skipping some"); 3671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return i; 3701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 3711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeint createFeatureRequest(WifiRequest& request, int subcmd, int enable) { 3731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, subcmd); 3751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 3761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 3771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 3801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_ENABLE_FEATURE, enable); 3811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 3821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 3831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 3841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 3861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 3871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 3881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 3891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 390922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndeclass FullScanResultsCommand : public WifiCommand 391922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde{ 392922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int *mParams; 393922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler mHandler; 394922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndepublic: 395922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde FullScanResultsCommand(wifi_interface_handle iface, int id, int *params, 396922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler) 397d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("FullScanResultsCommand", iface, id), mParams(params), mHandler(handler) 398922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde { } 399922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 400922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int createRequest(WifiRequest& request, int subcmd, int enable) { 401922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = request.create(GOOGLE_OUI, subcmd); 402922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 403922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 404922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 405922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 406922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 407922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(GSCAN_ENABLE_FULL_SCAN_RESULTS, enable); 408922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 409922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 410922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 411922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 412922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde request.attr_end(data); 413922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 414922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 415922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 416922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 417922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int start() { 418a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Enabling Full scan results"); 419922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde WifiRequest request(familyId(), ifaceId()); 420922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 1); 421922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 422922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to create request; result = %d", result); 423922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 424922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 425922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 426922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 427922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 428922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = requestResponse(request); 429922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 430922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to enable full scan results; result = %d", result); 431922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 432922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 433922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 434922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 435922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 436922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 437922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 438922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde virtual int cancel() { 439a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Disabling Full scan results"); 440922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 441922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde WifiRequest request(familyId(), ifaceId()); 442922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 0); 443922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 444922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to create request; result = %d", result); 445922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } else { 446922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = requestResponse(request); 447922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 448922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to disable full scan results;result = %d", result); 449922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 450922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 451922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 452922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 453922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 454922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 455922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 456922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 457922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGD("Request complete!"); 458922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde /* Nothing to do on response! */ 459922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return NL_SKIP; 460922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 461922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 462922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde virtual int handleEvent(WifiEvent& event) { 463a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Full scan results: Got an event"); 46477e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin return wifi_handle_full_scan_event(id(), event, mHandler); 465922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 466922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 467922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde}; 468922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde///////////////////////////////////////////////////////////////////////////// 4691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass ScanCommand : public WifiCommand 4711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 4721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_cmd_params *mParams; 4731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result_handler mHandler; 4741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 4751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params, 4761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result_handler handler) 47777e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin : WifiCommand("ScanCommand", iface, id), mParams(params), mHandler(handler) 4781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 4791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createSetupRequest(WifiRequest& request) { 4811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_CONFIG); 4821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 4871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BASE_PERIOD, mParams->base_period); 4881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BUCKETS, mParams->num_buckets); 4931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < mParams->num_buckets; i++) { 4981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr * bucket = request.attr_start(i); // next bucket 4991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID, mParams->buckets[i].bucket); 5001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_PERIOD, mParams->buckets[i].period); 5041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 507922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKETS_BAND, 508922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mParams->buckets[i].band); 509922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 510922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 511922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 51225a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT, 51325a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin mParams->buckets[i].step_count); 51425a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin if (result < 0) { 51525a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin return result; 51625a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin } 51725a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD, 51825a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin mParams->buckets[i].max_period); 51925a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin if (result < 0) { 52025a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin return result; 52125a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin } 522922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_EVENTS, 523922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mParams->buckets[i].report_events); 524922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 525922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 526922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 527922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 5281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, 5291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mParams->buckets[i].num_channels); 5301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 534922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (mParams->buckets[i].num_channels) { 535922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde nlattr *channels = request.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS); 536ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV(" channels: "); 537922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde for (int j = 0; j < mParams->buckets[i].num_channels; j++) { 538922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(j, mParams->buckets[i].channels[j].channel); 539ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV(" %u", mParams->buckets[i].channels[j].channel); 540659515a05a813cf672aa8d50161f76425afa781fPierre Vandwalle 541922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 542922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 543922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 5441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 545922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde request.attr_end(channels); 5461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(bucket); 5491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 5521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 5531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createScanConfigRequest(WifiRequest& request) { 5561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SCAN_CONFIG); 5571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 5621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, mParams->max_ap_per_scan); 5631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 567bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD, 568bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande mParams->report_threshold_percent); 5691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 573bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande int num_scans = mParams->report_threshold_num_scans; 57409f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde 57509f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, num_scans); 5761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 5811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 5821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createStartRequest(WifiRequest& request) { 5851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 5861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createStopRequest(WifiRequest& request) { 5891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0); 5901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int start() { 593a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("GSCAN start"); 5941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 5951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createSetupRequest(request); 5961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 5971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create setup request; result = %d", result); 5981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 6021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to configure setup; result = %d", result); 6041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.destroy(); 6081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createScanConfigRequest(request); 6101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create scan config request; result = %d", result); 6121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 6161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to configure scan; result = %d", result); 6181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 621a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV(" ....starting scan"); 6221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createStartRequest(request); 6241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create start request; result = %d", result); 6261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 6309a23388d5a9f58f106169700bb179de0a4af7840Ashwin registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 63177e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 6329a23388d5a9f58f106169700bb179de0a4af7840Ashwin 6331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 6341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to start scan; result = %d", result); 636de37675b218f0c685512417d914dff60f3b4b115Ashwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 6371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 63877e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 6391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int cancel() { 645a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Stopping scan"); 6461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 6481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createStopRequest(request); 6491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create stop request; result = %d", result); 6511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 6521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 6531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to stop scan; result = %d", result); 6551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 658082cb621b1dd1ad150a747d5010fed0888ae416cVinit Deshpande unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 6591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 66077e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 6611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 6621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 6651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* Nothing to do on response! */ 6661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 6671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleEvent(WifiEvent& event) { 670a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Got a scan results event"); 671eaf59b2182588ab2e921741c772070281840e89bNavtej Singh Mann //event.log(); 6721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 6741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = event.get_vendor_data_len(); 6759a23388d5a9f58f106169700bb179de0a4af7840Ashwin int event_id = event.get_vendor_subcmd(); 6761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6772b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if ((event_id == GSCAN_EVENT_COMPLETE_SCAN) || 6782b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin (event_id == GSCAN_EVENT_SCAN_RESULTS_AVAILABLE)) { 6799a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (vendor_data == NULL || len != 4) { 6802b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("Bad event data!"); 6819a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 6829a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 6839a23388d5a9f58f106169700bb179de0a4af7840Ashwin wifi_scan_event evt_type; 6849a23388d5a9f58f106169700bb179de0a4af7840Ashwin evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA); 6852b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGV("Received event type %d", evt_type); 68689296a7fc953e68649cdb1366d22376c034ace05Mitchell Wills if(*mHandler.on_scan_event) 6872b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin (*mHandler.on_scan_event)(id(), evt_type); 68877e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin } else if (event_id == GSCAN_EVENT_FULL_SCAN_RESULTS) { 68977e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin wifi_handle_full_scan_event(id(), event, mHandler); 6909a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 6911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 6921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 6941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_start_gscan( 6961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_request_id id, 6971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_interface_handle iface, 6981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_cmd_params params, 6991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result_handler handler) 7001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 7011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 7021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 703a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Starting GScan, halHandle = %p", handle); 7041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ScanCommand *cmd = new ScanCommand(iface, id, ¶ms, handler); 7066af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 7076af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 7086af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 7096af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 7106af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 7116af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 7126af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 713a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann if (result != WIFI_SUCCESS) { 714a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann wifi_unregister_cmd(handle, id); 7156af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 7166af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 717a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann } 718a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann return result; 7191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 7201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface) 7221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 7231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 724a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Stopping GScan, wifi_request_id = %d, halHandle = %p", id, handle); 7251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 726d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande if (id == -1) { 727922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler; 728922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_cmd_params dummy_params; 729922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 730922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde memset(&handler, 0, sizeof(handler)); 731922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 732922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler); 7336af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 734922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde cmd->cancel(); 73528237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 736922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 737922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 738922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 739fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 7401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 7411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 742922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_enable_full_scan_results( 743922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_request_id id, 744922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_interface_handle iface, 745922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler) 746922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde{ 747922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 748922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int params_dummy; 749a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann 750a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Enabling full scan results, halHandle = %p", handle); 751922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 752922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, ¶ms_dummy, handler); 7536af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 7546af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 7556af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 7566af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 7576af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 7586af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 7596af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 760a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann if (result != WIFI_SUCCESS) { 761a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann wifi_unregister_cmd(handle, id); 7626af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 7636af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 764a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann } 765a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann return result; 766922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde} 767922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 76877e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwinint wifi_handle_full_scan_event( 76977e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin wifi_request_id id, 77077e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin WifiEvent& event, 77177e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin wifi_scan_result_handler handler) 77277e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin{ 77377e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 77477e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin unsigned int len = event.get_vendor_data_len(); 77577e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin 7762b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (vendor_data == NULL || len < sizeof(wifi_gscan_full_result_t)) { 77777e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin ALOGI("Full scan results: No scan results found"); 77877e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin return NL_SKIP; 77977e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin } 78077e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin 7812b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data(); 7822b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin /* To protect against corrupted data, put a ceiling */ 7832b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin int ie_len = min(MAX_PROBE_RESP_IE_LEN, drv_res->ie_length); 7842b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_scan_result *full_scan_result; 7852b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_result_t *fixed = &drv_res->fixed; 78677e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin 787dc30cd78fad72d108d327285a2ba899b331c7992Ashwin if ((ie_len + offsetof(wifi_gscan_full_result_t, ie_data)) > len) { 788dc30cd78fad72d108d327285a2ba899b331c7992Ashwin ALOGE("BAD event data, len %d ie_len %d fixed length %d!\n", len, 789dc30cd78fad72d108d327285a2ba899b331c7992Ashwin ie_len, offsetof(wifi_gscan_full_result_t, ie_data)); 790dc30cd78fad72d108d327285a2ba899b331c7992Ashwin return NL_SKIP; 791dc30cd78fad72d108d327285a2ba899b331c7992Ashwin } 7922b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin full_scan_result = (wifi_scan_result *) malloc((ie_len + offsetof(wifi_scan_result, ie_data))); 7932b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (!full_scan_result) { 7942b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGE("Full scan results: Can't malloc!\n"); 7952b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return NL_SKIP; 7962b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 7972b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin convert_to_hal_result(full_scan_result, fixed); 7982b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin full_scan_result->ie_length = ie_len; 7992b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memcpy(full_scan_result->ie_data, drv_res->ie_data, ie_len); 8002b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if(handler.on_full_scan_result) 8012b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin handler.on_full_scan_result(id, full_scan_result, drv_res->scan_ch_bucket); 8022b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin 8031c8586503c74fd8bebb5e8b83beed989c33613eeSreenath Sharma ALOGV("Full scan result: %-32s %02x:%02x:%02x:%02x:%02x:%02x %d %d %lld %lld %lld %x %d\n", 8042b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin fixed->ssid, fixed->bssid[0], fixed->bssid[1], fixed->bssid[2], fixed->bssid[3], 8052b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin fixed->bssid[4], fixed->bssid[5], fixed->rssi, fixed->channel, fixed->ts, 8062b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin fixed->rtt, fixed->rtt_sd, drv_res->scan_ch_bucket, drv_res->ie_length); 8072b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin free(full_scan_result); 80877e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin return NL_SKIP; 80977e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin} 81077e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin 81177e3df794cfaf6f280b0230cc2a0eaa818606e6aAshwin 812922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface) 813922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde{ 814a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Disabling full scan results"); 815922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 816922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 817922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if(id == -1) { 818922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler; 819922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 820922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int params_dummy; 821922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 822922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde memset(&handler, 0, sizeof(handler)); 823922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, 0, ¶ms_dummy, handler); 8246af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 825922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde cmd->cancel(); 82628237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 827922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 828922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 829922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 830fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 831922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde} 832922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 833922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 8341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 8351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass GetScanResultsCommand : public WifiCommand { 837bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande wifi_cached_scan_results *mScans; 838e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int mMax; 8391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int *mNum; 8401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int mRetrieved; 8411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde byte mFlush; 8421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int mCompleted; 8431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 8441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetScanResultsCommand(wifi_interface_handle iface, byte flush, 845bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande wifi_cached_scan_results *results, int max, int *num) 846d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("GetScanResultsCommand", iface, -1), mScans(results), mMax(max), mNum(num), 8472b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin mRetrieved(0), mFlush(flush), mCompleted(0) 8481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 8491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createRequest(WifiRequest& request, int num, byte flush) { 8511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_SCAN_RESULTS); 8521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 8531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 8571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num); 8581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 8591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_FLUSH_RESULTS, flush); 8631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 8641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 8681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 8691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int execute() { 8721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 873a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("retrieving %d scan results", mMax); 8741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 875e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande for (int i = 0; i < 10 && mRetrieved < mMax; i++) { 876bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande int num_to_retrieve = mMax - mRetrieved; 87779c41bc9ff10a322cf6cacc51b80707d5ba5a4eeVinit Deshpande // ALOGI("retrieving %d scan results in one shot", num_to_retrieve); 878bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande int result = createRequest(request, num_to_retrieve, mFlush); 8791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 8801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create request"); 8811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int prev_retrieved = mRetrieved; 8851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 8871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 8891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to retrieve scan results; result = %d", result); 8901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (mRetrieved == prev_retrieved || mCompleted) { 8941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* no more items left to retrieve */ 8951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde break; 8961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.destroy(); 8991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 901aab2ce80bab0221da737f64d15bae68caae21badNavtej Singh Mann ALOGV("GetScanResults read %d results", mRetrieved); 9021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde *mNum = mRetrieved; 9031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 9041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 907a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("In GetScanResultsCommand::handleResponse"); 9081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (reply.get_cmd() != NL80211_CMD_VENDOR) { 9101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 9111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 9121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int id = reply.get_vendor_id(); 9151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int subcmd = reply.get_vendor_subcmd(); 9161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 917a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Id = %0x, subcmd = %d", id, subcmd); 9181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* 9201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (subcmd != GSCAN_SUBCMD_SCAN_RESULTS) { 9211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Invalid response to GetScanResultsCommand; ignoring it"); 9221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 9231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde */ 9251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 9271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = reply.get_vendor_data_len(); 9281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (vendor_data == NULL || len == 0) { 9301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("no vendor data in GetScanResults response; ignoring it"); 9311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 9321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 9351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE) { 9361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mCompleted = it.get_u8(); 937ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("retrieved mCompleted flag : %d", mCompleted); 9381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS || it.get_type() == 0) { 9392b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin int scan_id = 0, flags = 0, num = 0, scan_ch_bucket_mask = 0; 9401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) { 9411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) { 942bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande scan_id = it2.get_u32(); 943ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("retrieved scan_id : 0x%0x", scan_id); 9441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS) { 945bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande flags = it2.get_u8(); 946ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("retrieved scan_flags : 0x%0x", flags); 9471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { 9481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde num = it2.get_u32(); 949ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("retrieved num_results: %d", num); 9502b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } else if (it2.get_type() == GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK) { 9512b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin scan_ch_bucket_mask = it2.get_u32(); 9522b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGD("retrieved scan_ch_bucket_mask: %x", scan_ch_bucket_mask); 9532b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS && num) { 954e900b04a91fd87e4d706be7ae3499d5fb9995188Kevin Cernekee if (mRetrieved >= mMax) { 955e900b04a91fd87e4d706be7ae3499d5fb9995188Kevin Cernekee ALOGW("Stored %d scans, ignoring excess results", mRetrieved); 956e900b04a91fd87e4d706be7ae3499d5fb9995188Kevin Cernekee break; 957e900b04a91fd87e4d706be7ae3499d5fb9995188Kevin Cernekee } 958a1797bbd4753d67ff6a48028710467d3fc68a4d9Sreenath Sharma num = min(num, (int)(it2.get_len()/sizeof(wifi_gscan_result))); 9592b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin num = min(num, (int)MAX_AP_CACHE_PER_SCAN); 9602b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGV("Copying %d scan results", num); 9612b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_result_t *results = (wifi_gscan_result_t *)it2.get_data(); 9622b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_scan_result *mScanResults = mScans[mRetrieved].results; 9632b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin 9641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < num; i++) { 9652b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_result_t *result = &results[i]; 9662b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin convert_to_hal_result(&mScanResults[i], result); 9672b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin mScanResults[i].ie_length = 0; 968ec74fa4fcb49a35e6af54e086e63692b37d21b02Vinit Deshpande ALOGV("%02d %-32s %02x:%02x:%02x:%02x:%02x:%02x %04d", i, 9691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ssid, result->bssid[0], result->bssid[1], result->bssid[2], 97009f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde result->bssid[3], result->bssid[4], result->bssid[5], 97109f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde result->rssi); 9721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 973bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande mScans[mRetrieved].scan_id = scan_id; 974bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande mScans[mRetrieved].flags = flags; 975bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande mScans[mRetrieved].num_results = num; 9762b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin mScans[mRetrieved].buckets_scanned = scan_ch_bucket_mask; 9771b166fb091b262273e129c6019c4d07a5ded665dNavtej Singh Mann ALOGV("Setting result of scan_id : 0x%0x", mScans[mRetrieved].scan_id); 978bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande mRetrieved++; 9791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 9801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGW("Ignoring invalid attribute type = %d, size = %d", 9811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde it.get_type(), it.get_len()); 9821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 9851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGW("Ignoring invalid attribute type = %d, size = %d", 9861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde it.get_type(), it.get_len()); 9871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 989aab2ce80bab0221da737f64d15bae68caae21badNavtej Singh Mann ALOGV("GetScanResults read %d results", mRetrieved); 9901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_OK; 9911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 9931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush, 995bcd42ae7e431d321090080aa00865b6fe4ab95e0Vinit Deshpande int max, wifi_cached_scan_results *results, int *num) { 996a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Getting cached scan results, iface handle = %p, num = %d", iface, *num); 9971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 998e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num); 9996af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 10006af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error err = (wifi_error)cmd->execute(); 10016af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 100242b1646c415b1d3cff220eb3491dc6960d610fafVinit Deshpande return err; 10031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 10041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 10061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass BssidHotlistCommand : public WifiCommand 10081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 10091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprivate: 10101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_bssid_hotlist_params mParams; 10111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_hotlist_ap_found_handler mHandler; 10121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde static const int MAX_RESULTS = 64; 10131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result mResults[MAX_RESULTS]; 10141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 10151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde BssidHotlistCommand(wifi_interface_handle handle, int id, 10161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) 1017d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("BssidHotlistCommand", handle, id), mParams(params), mHandler(handler) 10181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 10191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createSetupRequest(WifiRequest& request) { 10211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST); 10221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 10271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1); 10281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1032f0d5070a931327e6356d765478069b9e66452a5bAshwin result = request.put_u32(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size); 1033f0d5070a931327e6356d765478069b9e66452a5bAshwin if (result < 0) { 1034f0d5070a931327e6356d765478069b9e66452a5bAshwin return result; 1035f0d5070a931327e6356d765478069b9e66452a5bAshwin } 1036f0d5070a931327e6356d765478069b9e66452a5bAshwin 103766d82546960bb2408e1aa31856a3f9a6a400681fInsun Song result = request.put_u32(GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT, mParams.num_bssid); 103866d82546960bb2408e1aa31856a3f9a6a400681fInsun Song if (result < 0) { 103966d82546960bb2408e1aa31856a3f9a6a400681fInsun Song return result; 104066d82546960bb2408e1aa31856a3f9a6a400681fInsun Song } 104166d82546960bb2408e1aa31856a3f9a6a400681fInsun Song 10421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS); 1043886a7c99f8664295fe233034cac84d6253324641Pierre Vandwalle for (int i = 0; i < mParams.num_bssid; i++) { 10441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *attr2 = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_ELEM); 10451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (attr2 == NULL) { 10461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_OUT_OF_MEMORY; 10471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1048e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid); 10491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1052e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high); 10531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1056e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low); 10571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr2); 10611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr); 10641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 10651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createTeardownRequest(WifiRequest& request) { 10691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST); 10701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 10751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1); 10761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS); 10811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr); 10821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 10831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int start() { 1087886a7c99f8664295fe233034cac84d6253324641Pierre Vandwalle ALOGI("Executing hotlist setup request, num = %d", mParams.num_bssid); 10881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 10891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createSetupRequest(request); 10901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 10951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Failed to execute hotlist setup request, result = %d", result); 1097f0d5070a931327e6356d765478069b9e66452a5bAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1098f0d5070a931327e6356d765478069b9e66452a5bAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 10991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1102886a7c99f8664295fe233034cac84d6253324641Pierre Vandwalle ALOGI("Successfully set %d APs in the hotlist ", mParams.num_bssid); 11031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 11041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1108f0d5070a931327e6356d765478069b9e66452a5bAshwin registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1109f0d5070a931327e6356d765478069b9e66452a5bAshwin registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 11101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 11121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 1113f0d5070a931327e6356d765478069b9e66452a5bAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1114f0d5070a931327e6356d765478069b9e66452a5bAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 11151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully restarted the scan"); 11191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int cancel() { 11231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* unregister event handler */ 1124f0d5070a931327e6356d765478069b9e66452a5bAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1125f0d5070a931327e6356d765478069b9e66452a5bAshwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 11261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* create set hotlist message with empty hotlist */ 11271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 11281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createTeardownRequest(request); 11291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 11341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Successfully reset APs in current hotlist"); 11391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 11431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* Nothing to do on response! */ 11441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 11451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleEvent(WifiEvent& event) { 1148f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGI("Hotlist AP event"); 1149f0d5070a931327e6356d765478069b9e66452a5bAshwin int event_id = event.get_vendor_subcmd(); 115009f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde // event.log(); 11511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 11531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = event.get_vendor_data_len(); 11541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (vendor_data == NULL || len == 0) { 11561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("No scan results found"); 11571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 11581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS); 11611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11622b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin int num = len / sizeof(wifi_gscan_result_t); 11632b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_result_t *inp = (wifi_gscan_result_t *)event.get_vendor_data(); 11641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde num = min(MAX_RESULTS, num); 11652b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin for (int i = 0; i < num; i++, inp++) { 11662b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin convert_to_hal_result(&(mResults[i]), inp); 11672b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 11681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1169f0d5070a931327e6356d765478069b9e66452a5bAshwin if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_FOUND) { 1170f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGI("FOUND %d hotlist APs", num); 1171f0d5070a931327e6356d765478069b9e66452a5bAshwin if (*mHandler.on_hotlist_ap_found) 1172f0d5070a931327e6356d765478069b9e66452a5bAshwin (*mHandler.on_hotlist_ap_found)(id(), num, mResults); 1173f0d5070a931327e6356d765478069b9e66452a5bAshwin } else if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_LOST) { 1174f0d5070a931327e6356d765478069b9e66452a5bAshwin ALOGI("LOST %d hotlist APs", num); 1175f0d5070a931327e6356d765478069b9e66452a5bAshwin if (*mHandler.on_hotlist_ap_lost) 1176f0d5070a931327e6356d765478069b9e66452a5bAshwin (*mHandler.on_hotlist_ap_lost)(id(), num, mResults); 1177f0d5070a931327e6356d765478069b9e66452a5bAshwin } 11781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 11791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 11811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 118289a9a4cffbcee6af504c61ff575a008194070c82Ashwinclass ePNOCommand : public WifiCommand 118389a9a4cffbcee6af504c61ff575a008194070c82Ashwin{ 118489a9a4cffbcee6af504c61ff575a008194070c82Ashwinprivate: 11852b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_epno_params epno_params; 118689a9a4cffbcee6af504c61ff575a008194070c82Ashwin wifi_epno_handler mHandler; 11872b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_scan_result mResults[MAX_EPNO_NETWORKS]; 118889a9a4cffbcee6af504c61ff575a008194070c82Ashwinpublic: 118989a9a4cffbcee6af504c61ff575a008194070c82Ashwin ePNOCommand(wifi_interface_handle handle, int id, 11902b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin const wifi_epno_params *params, wifi_epno_handler handler) 1191d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("ePNOCommand", handle, id), mHandler(handler) 119289a9a4cffbcee6af504c61ff575a008194070c82Ashwin { 11932b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (params != NULL) { 11942b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memcpy(&epno_params, params, sizeof(wifi_epno_params)); 11952b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } else { 11962b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memset(&epno_params, 0, sizeof(wifi_epno_params)); 11972b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 119889a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 119989a9a4cffbcee6af504c61ff575a008194070c82Ashwin int createSetupRequest(WifiRequest& request) { 12005a434343e3515e2c1e29b879ed67898206016f3fInsun Song if (epno_params.num_networks > MAX_EPNO_NETWORKS) { 12015a434343e3515e2c1e29b879ed67898206016f3fInsun Song ALOGE("wrong epno num_networks:%d", epno_params.num_networks); 12025a434343e3515e2c1e29b879ed67898206016f3fInsun Song return WIFI_ERROR_INVALID_ARGS; 12035a434343e3515e2c1e29b879ed67898206016f3fInsun Song } 120489a9a4cffbcee6af504c61ff575a008194070c82Ashwin int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID); 120589a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 120689a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 120789a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 120889a9a4cffbcee6af504c61ff575a008194070c82Ashwin nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 120989a9a4cffbcee6af504c61ff575a008194070c82Ashwin result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1); 121089a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 121189a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 121289a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 121389a9a4cffbcee6af504c61ff575a008194070c82Ashwin 12142b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR, 12152b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin (u8)epno_params.min5GHz_rssi); 12162b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12172b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12182b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12192b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR, 12202b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin (u8)epno_params.min24GHz_rssi); 12212b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12222b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12232b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12242b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX, 12252b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin epno_params.initial_score_max); 12262b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12272b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12282b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12292b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS, 12302b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin epno_params.current_connection_bonus); 12312b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12322b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12332b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12342b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS, 12352b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin epno_params.same_network_bonus); 12362b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12372b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12382b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12392b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS, 12402b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin epno_params.secure_bonus); 12412b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12422b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12432b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12442b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_5G_BONUS, 12452b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin epno_params.band5GHz_bonus); 12462b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (result < 0) { 12472b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return result; 12482b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 12492b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_NUM, 12502b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin epno_params.num_networks); 125189a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 125289a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 125389a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 125489a9a4cffbcee6af504c61ff575a008194070c82Ashwin struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_EPNO_SSID_LIST); 12552b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_epno_network *ssid_list = epno_params.networks; 12562b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin for (int i = 0; i < epno_params.num_networks; i++) { 125789a9a4cffbcee6af504c61ff575a008194070c82Ashwin nlattr *attr2 = request.attr_start(i); 125889a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (attr2 == NULL) { 125989a9a4cffbcee6af504c61ff575a008194070c82Ashwin return WIFI_ERROR_OUT_OF_MEMORY; 126089a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 12612b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put(GSCAN_ATTRIBUTE_EPNO_SSID, ssid_list[i].ssid, DOT11_MAX_SSID_LEN); 12622b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("PNO network: SSID %s flags %x auth %x", ssid_list[i].ssid, 12632b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ssid_list[i].flags, 12642b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ssid_list[i].auth_bit_field); 126589a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 126689a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 126789a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 12682b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_SSID_LEN, strlen(ssid_list[i].ssid)); 126989a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 127089a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 127189a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 12722b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_FLAGS, ssid_list[i].flags); 127389a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 127489a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 127589a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 12762b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_AUTH, ssid_list[i].auth_bit_field); 127789a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 127889a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 127989a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 128089a9a4cffbcee6af504c61ff575a008194070c82Ashwin request.attr_end(attr2); 128189a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 128289a9a4cffbcee6af504c61ff575a008194070c82Ashwin request.attr_end(attr); 128389a9a4cffbcee6af504c61ff575a008194070c82Ashwin request.attr_end(data); 128489a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 128589a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 128689a9a4cffbcee6af504c61ff575a008194070c82Ashwin 128789a9a4cffbcee6af504c61ff575a008194070c82Ashwin int createTeardownRequest(WifiRequest& request) { 128889a9a4cffbcee6af504c61ff575a008194070c82Ashwin int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID); 128989a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 129089a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 129189a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 129289a9a4cffbcee6af504c61ff575a008194070c82Ashwin 129389a9a4cffbcee6af504c61ff575a008194070c82Ashwin nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 129489a9a4cffbcee6af504c61ff575a008194070c82Ashwin result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1); 129589a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 129689a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 129789a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 129889a9a4cffbcee6af504c61ff575a008194070c82Ashwin request.attr_end(data); 129989a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 130089a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 130189a9a4cffbcee6af504c61ff575a008194070c82Ashwin 130289a9a4cffbcee6af504c61ff575a008194070c82Ashwin int start() { 13032b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("Executing ePNO setup request, num = %d", epno_params.num_networks); 130489a9a4cffbcee6af504c61ff575a008194070c82Ashwin WifiRequest request(familyId(), ifaceId()); 130589a9a4cffbcee6af504c61ff575a008194070c82Ashwin int result = createSetupRequest(request); 130689a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 130789a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 130889a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 130989a9a4cffbcee6af504c61ff575a008194070c82Ashwin 131089a9a4cffbcee6af504c61ff575a008194070c82Ashwin result = requestResponse(request); 131189a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 131289a9a4cffbcee6af504c61ff575a008194070c82Ashwin ALOGI("Failed to execute ePNO setup request, result = %d", result); 131389a9a4cffbcee6af504c61ff575a008194070c82Ashwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); 131489a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 131589a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 131689a9a4cffbcee6af504c61ff575a008194070c82Ashwin 13172b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("Successfully set %d SSIDs for ePNO", epno_params.num_networks); 131889a9a4cffbcee6af504c61ff575a008194070c82Ashwin registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); 131989a9a4cffbcee6af504c61ff575a008194070c82Ashwin ALOGI("successfully restarted the scan"); 132089a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 132189a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 132289a9a4cffbcee6af504c61ff575a008194070c82Ashwin 132389a9a4cffbcee6af504c61ff575a008194070c82Ashwin virtual int cancel() { 132489a9a4cffbcee6af504c61ff575a008194070c82Ashwin /* unregister event handler */ 132589a9a4cffbcee6af504c61ff575a008194070c82Ashwin unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); 132689a9a4cffbcee6af504c61ff575a008194070c82Ashwin /* create set hotlist message with empty hotlist */ 132789a9a4cffbcee6af504c61ff575a008194070c82Ashwin WifiRequest request(familyId(), ifaceId()); 132889a9a4cffbcee6af504c61ff575a008194070c82Ashwin int result = createTeardownRequest(request); 132989a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 133089a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 133189a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 133289a9a4cffbcee6af504c61ff575a008194070c82Ashwin 133389a9a4cffbcee6af504c61ff575a008194070c82Ashwin result = requestResponse(request); 133489a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (result < 0) { 133589a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 133689a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 133789a9a4cffbcee6af504c61ff575a008194070c82Ashwin 133889a9a4cffbcee6af504c61ff575a008194070c82Ashwin ALOGI("Successfully reset APs in current hotlist"); 133989a9a4cffbcee6af504c61ff575a008194070c82Ashwin return result; 134089a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 134189a9a4cffbcee6af504c61ff575a008194070c82Ashwin 134289a9a4cffbcee6af504c61ff575a008194070c82Ashwin virtual int handleResponse(WifiEvent& reply) { 134389a9a4cffbcee6af504c61ff575a008194070c82Ashwin /* Nothing to do on response! */ 134489a9a4cffbcee6af504c61ff575a008194070c82Ashwin return NL_SKIP; 134589a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 134689a9a4cffbcee6af504c61ff575a008194070c82Ashwin 134789a9a4cffbcee6af504c61ff575a008194070c82Ashwin virtual int handleEvent(WifiEvent& event) { 134889a9a4cffbcee6af504c61ff575a008194070c82Ashwin ALOGI("ePNO event"); 134989a9a4cffbcee6af504c61ff575a008194070c82Ashwin int event_id = event.get_vendor_subcmd(); 135089a9a4cffbcee6af504c61ff575a008194070c82Ashwin // event.log(); 135189a9a4cffbcee6af504c61ff575a008194070c82Ashwin 135289a9a4cffbcee6af504c61ff575a008194070c82Ashwin nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 135389a9a4cffbcee6af504c61ff575a008194070c82Ashwin int len = event.get_vendor_data_len(); 135489a9a4cffbcee6af504c61ff575a008194070c82Ashwin 135589a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (vendor_data == NULL || len == 0) { 135689a9a4cffbcee6af504c61ff575a008194070c82Ashwin ALOGI("No scan results found"); 135789a9a4cffbcee6af504c61ff575a008194070c82Ashwin return NL_SKIP; 135889a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 135989a9a4cffbcee6af504c61ff575a008194070c82Ashwin 13602b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memset(mResults, 0, sizeof(wifi_scan_result) * MAX_EPNO_NETWORKS); 136189a9a4cffbcee6af504c61ff575a008194070c82Ashwin 13622b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin unsigned int num = len / sizeof(wifi_pno_result_t); 13632b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin unsigned int i; 13642b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin num = min(MAX_EPNO_NETWORKS, num); 136589a9a4cffbcee6af504c61ff575a008194070c82Ashwin wifi_pno_result_t *res = (wifi_pno_result_t *) event.get_vendor_data(); 136689a9a4cffbcee6af504c61ff575a008194070c82Ashwin for (i = 0; i < num; i++) { 136789a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (res[i].flags == PNO_SSID_FOUND) { 136889a9a4cffbcee6af504c61ff575a008194070c82Ashwin memcpy(mResults[i].ssid, res[i].ssid, res[i].ssid_len); 136925a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin memcpy(mResults[i].bssid, res[i].bssid, sizeof(mac_addr)); 137025a0fb843d8b6d9141ccb435f1f9ee9a29d3afc6Ashwin 137189a9a4cffbcee6af504c61ff575a008194070c82Ashwin mResults[i].ssid[res[i].ssid_len] = '\0'; 137289a9a4cffbcee6af504c61ff575a008194070c82Ashwin mResults[i].channel = res[i].channel; 137389a9a4cffbcee6af504c61ff575a008194070c82Ashwin mResults[i].rssi = res[i].rssi; 137489a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 137589a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 137689a9a4cffbcee6af504c61ff575a008194070c82Ashwin if (*mHandler.on_network_found) 137789a9a4cffbcee6af504c61ff575a008194070c82Ashwin (*mHandler.on_network_found)(id(), num, mResults); 137889a9a4cffbcee6af504c61ff575a008194070c82Ashwin return NL_SKIP; 137989a9a4cffbcee6af504c61ff575a008194070c82Ashwin } 138089a9a4cffbcee6af504c61ff575a008194070c82Ashwin}; 138189a9a4cffbcee6af504c61ff575a008194070c82Ashwin 13821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface, 13831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) 13841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 13851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 13861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 13871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler); 13886af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 13896af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 13906af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 13916af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 13926af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 13936af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 13946af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 1395a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann if (result != WIFI_SUCCESS) { 1396a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann wifi_unregister_cmd(handle, id); 13976af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 13986af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 1399a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann } 1400a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann return result; 14011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 14021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface) 14041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1405fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 14061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 14071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 14101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass SignificantWifiChangeCommand : public WifiCommand 14121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1413e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande typedef struct { 1414e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mac_addr bssid; // BSSID 1415e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_channel channel; // channel frequency in MHz 1416e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int num_rssi; // number of rssi samples 1417e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_rssi rssi[8]; // RSSI history in db 1418e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande } wifi_significant_change_result_internal; 1419e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande 14201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprivate: 14211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_params mParams; 14221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_handler mHandler; 14231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde static const int MAX_RESULTS = 64; 1424e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_significant_change_result_internal mResultsBuffer[MAX_RESULTS]; 1425e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_significant_change_result *mResults[MAX_RESULTS]; 14261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 14271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde SignificantWifiChangeCommand(wifi_interface_handle handle, int id, 14281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_params params, wifi_significant_change_handler handler) 1429d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("SignificantWifiChangeCommand", handle, id), mParams(params), 1430d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande mHandler(handler) 14311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 14321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createSetupRequest(WifiRequest& request) { 14341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); 14351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 14361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 14401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1); 14411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 14421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE, mParams.rssi_sample_size); 14451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 14461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size); 14491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 14501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_MIN_BREACHING, mParams.min_breaching); 14531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 14541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1456f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song result = request.put_u16(GSCAN_ATTRIBUTE_NUM_BSSID, mParams.num_bssid); 1457f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (result < 0) { 1458f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song return result; 1459f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song } 1460f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (mParams.num_bssid != 0) { 1461f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song nlattr* attr = request.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS); 1462f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (attr == NULL) { 14631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_OUT_OF_MEMORY; 14641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1465f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song 1466f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song for (int i = 0; i < mParams.num_bssid; i++) { 1467f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song nlattr* attr2 = request.attr_start(i); 1468f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (attr2 == NULL) { 1469f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song return WIFI_ERROR_OUT_OF_MEMORY; 1470f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song } 1471f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid); 1472f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (result < 0) { 1473f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song return result; 1474f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song } 1475f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high); 1476f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (result < 0) { 1477f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song return result; 1478f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song } 1479f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low); 1480f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song if (result < 0) { 1481f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song return result; 1482f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song } 1483f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song request.attr_end(attr2); 14841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1486f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song request.attr_end(attr); 1487f57fbe161190c2910c349b2b3af0b9b27c6a1c91Insun Song } 14881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 14891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createTeardownRequest(WifiRequest& request) { 14941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); 14951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 14961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 14971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 14981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 14991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 15001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1); 15011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 15061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int start() { 15101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Set significant wifi change config"); 15111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 15121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createSetupRequest(request); 15141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 15191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("failed to set significant wifi change config %d", result); 15211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully set significant wifi change config"); 15251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 15271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 15321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 15341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 15361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully restarted the scan"); 15401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int cancel() { 15441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* unregister event handler */ 15451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 15461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* create set significant change monitor message with empty hotlist */ 15481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 15491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createTeardownRequest(request); 15511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 15561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 15571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully reset significant wifi change config"); 15611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 15621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 15651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* Nothing to do on response! */ 15661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 15671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleEvent(WifiEvent& event) { 1570a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Got a significant wifi change event"); 15711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 15731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = event.get_vendor_data_len(); 15741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (vendor_data == NULL || len == 0) { 15761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("No scan results found"); 15771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 15781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde typedef struct { 15811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde uint16_t flags; 15821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde uint16_t channel; 15831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mac_addr bssid; 15849a23388d5a9f58f106169700bb179de0a4af7840Ashwin s8 rssi_history[8]; 15851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } ChangeInfo; 15861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int num = min(len / sizeof(ChangeInfo), MAX_RESULTS); 15881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ChangeInfo *ci = (ChangeInfo *)event.get_vendor_data(); 15891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < num; i++) { 1591e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande memcpy(mResultsBuffer[i].bssid, ci[i].bssid, sizeof(mac_addr)); 1592e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mResultsBuffer[i].channel = ci[i].channel; 1593e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mResultsBuffer[i].num_rssi = 8; 15949a23388d5a9f58f106169700bb179de0a4af7840Ashwin for (int j = 0; j < mResultsBuffer[i].num_rssi; j++) 15959a23388d5a9f58f106169700bb179de0a4af7840Ashwin mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j]; 1596e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i])); 15971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 15981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1599a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann ALOGV("Retrieved %d scan results", num); 16001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 16011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (num != 0) { 16021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde (*mHandler.on_significant_change)(id(), num, mResults); 16031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 16041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGW("No significant change reported"); 16051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 16061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 16071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 16081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 16091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 16101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 16111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface, 16121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_params params, wifi_significant_change_handler handler) 16131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 16141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 16151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 16161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand( 16171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde iface, id, params, handler); 16186af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 16196af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 16206af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 16216af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 16226af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 16236af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 16246af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 1625a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann if (result != WIFI_SUCCESS) { 1626a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann wifi_unregister_cmd(handle, id); 16276af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 16286af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 1629a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann } 1630a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann return result; 16311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 16321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 16331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface) 16341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1635fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 16361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 163789a9a4cffbcee6af504c61ff575a008194070c82Ashwin 163889a9a4cffbcee6af504c61ff575a008194070c82Ashwinwifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface) 163989a9a4cffbcee6af504c61ff575a008194070c82Ashwin{ 16402b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (id == -1) { 16412b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_epno_handler handler; 16422b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_handle handle = getWifiHandle(iface); 16432b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin 16442b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin memset(&handler, 0, sizeof(handler)); 16452b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ePNOCommand *cmd = new ePNOCommand(iface, id, NULL, handler); 16466af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 16472b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin cmd->cancel(); 16482b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin cmd->releaseRef(); 16492b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return WIFI_SUCCESS; 16502b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 1651fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 165289a9a4cffbcee6af504c61ff575a008194070c82Ashwin} 16532672aa697b5dea852e9c3cc210ff2ee3a075d97cPierre Vandwalle 16542672aa697b5dea852e9c3cc210ff2ee3a075d97cPierre Vandwallewifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface, 165589296a7fc953e68649cdb1366d22376c034ace05Mitchell Wills const wifi_epno_params *params, wifi_epno_handler handler) 16562672aa697b5dea852e9c3cc210ff2ee3a075d97cPierre Vandwalle{ 16576af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_handle handle = getWifiHandle(iface); 16586af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma 16596af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma ePNOCommand *cmd = new ePNOCommand(iface, id, params, handler); 16606af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 16616af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 16626af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 16636af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 16646af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 16656af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 16666af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 16676af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 16686af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_unregister_cmd(handle, id); 16696af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 16706af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 16716af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 16726af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 16732672aa697b5dea852e9c3cc210ff2ee3a075d97cPierre Vandwalle} 16742672aa697b5dea852e9c3cc210ff2ee3a075d97cPierre Vandwalle 1675810c949db9c60baa02684a50d71026727c357cd2Ashwin 1676f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng//////////////////////////////////////////////////////////////////////////////// 1677f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1678f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ngclass AnqpoConfigureCommand : public WifiCommand 1679f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng{ 1680f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int num_hs; 1681f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng wifi_passpoint_network *mNetworks; 1682f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng wifi_passpoint_event_handler mHandler; 16832b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_scan_result *mResult; 1684f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ngpublic: 1685f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng AnqpoConfigureCommand(wifi_request_id id, wifi_interface_handle iface, 1686f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int num, wifi_passpoint_network *hs_list, wifi_passpoint_event_handler handler) 1687d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande : WifiCommand("AnqpoConfigureCommand", iface, id), num_hs(num), mNetworks(hs_list), 1688d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande mHandler(handler) 1689f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng { 16902b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin mResult = NULL; 1691f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1692f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1693f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int createRequest(WifiRequest& request, int val) { 1694f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1695f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_ANQPO_CONFIG); 1696f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, num_hs); 1697f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result < 0) { 1698f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1699f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1700f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1701f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1702f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1703f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_ANQPO_HS_LIST); 1704f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng for (int i = 0; i < num_hs; i++) { 1705f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng nlattr *attr2 = request.attr_start(i); 1706f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (attr2 == NULL) { 1707f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return WIFI_ERROR_OUT_OF_MEMORY; 1708f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1709f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, mNetworks[i].id); 1710f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result < 0) { 1711f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1712f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1713f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, mNetworks[i].realm, 256); 1714f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result < 0) { 1715f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1716f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1717f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID, 1718f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng mNetworks[i].roamingConsortiumIds, 128); 1719f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result < 0) { 1720f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1721f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1722f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, mNetworks[i].plmn, 3); 1723f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result < 0) { 1724f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1725f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1726f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1727f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng request.attr_end(attr2); 1728f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1729f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1730f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng request.attr_end(attr); 1731f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng request.attr_end(data); 1732f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1733f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return WIFI_SUCCESS; 1734f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1735f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1736f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int start() { 1737f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1738f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng WifiRequest request(familyId(), ifaceId()); 1739f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int result = createRequest(request, num_hs); 1740f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result != WIFI_SUCCESS) { 1741f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGE("failed to create request; result = %d", result); 1742f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1743f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1744f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1745f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); 1746f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1747f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = requestResponse(request); 1748f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result != WIFI_SUCCESS) { 1749f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGE("failed to set ANQPO networks; result = %d", result); 1750f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); 1751f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1752f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1753f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1754f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return result; 1755f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1756f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1757f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng virtual int cancel() { 1758f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1759f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng WifiRequest request(familyId(), ifaceId()); 1760f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int result = createRequest(request, 0); 1761f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result != WIFI_SUCCESS) { 1762f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGE("failed to create request; result = %d", result); 1763f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } else { 1764f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng result = requestResponse(request); 1765f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (result != WIFI_SUCCESS) { 1766f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGE("failed to reset ANQPO networks;result = %d", result); 1767f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1768f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1769f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1770f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); 1771f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return WIFI_SUCCESS; 1772f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1773f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1774f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng virtual int handleResponse(WifiEvent& reply) { 1775f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGD("Request complete!"); 1776f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng /* Nothing to do on response! */ 1777f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return NL_SKIP; 1778f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1779f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1780f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng virtual int handleEvent(WifiEvent& event) { 1781f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng typedef struct { 1782f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng u16 channel; /* channel of GAS protocol */ 1783f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng u8 dialog_token; /* GAS dialog token */ 1784f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng u8 fragment_id; /* fragment id */ 1785f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng u16 status_code; /* status code on GAS completion */ 1786f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng u16 data_len; /* length of data to follow */ 1787f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng u8 data[1]; /* variable length specified by data_len */ 1788f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } wifi_anqp_gas_resp; 1789f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1790f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGI("ANQPO hotspot matched event!"); 1791f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1792f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 1793f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng unsigned int len = event.get_vendor_data_len(); 1794f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1795f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if (vendor_data == NULL || len < sizeof(wifi_scan_result)) { 1796f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng ALOGI("No scan results found"); 1797f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return NL_SKIP; 1798f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 17992b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin mResult = (wifi_scan_result *)malloc(sizeof(wifi_scan_result)); 18002b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin if (!mResult) { 18012b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin return NL_SKIP; 18022b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin } 18032b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data(); 18042b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin wifi_gscan_result_t *fixed = &drv_res->fixed; 18052b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin convert_to_hal_result(mResult, fixed); 1806f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 18072b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin byte *anqp = (byte *)drv_res + offsetof(wifi_gscan_full_result_t, ie_data) + drv_res->ie_length; 1808f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng wifi_anqp_gas_resp *gas = (wifi_anqp_gas_resp *)anqp; 1809f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int anqp_len = offsetof(wifi_anqp_gas_resp, data) + gas->data_len; 1810f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng int networkId = *(int *)((byte *)anqp + anqp_len); 1811f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 18122b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%-32s\t", mResult->ssid); 1813f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 18142b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", mResult->bssid[0], mResult->bssid[1], 18152b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin mResult->bssid[2], mResult->bssid[3], mResult->bssid[4], mResult->bssid[5]); 1816f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 18172b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%d\t", mResult->rssi); 18182b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%d\t", mResult->channel); 18192b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%lld\t", mResult->ts); 18202b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%lld\t", mResult->rtt); 18212b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin ALOGI("%lld\n", mResult->rtt_sd); 1822f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1823f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng if(*mHandler.on_passpoint_network_found) 18242b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin (*mHandler.on_passpoint_network_found)(id(), networkId, mResult, anqp_len, anqp); 18252b31c56930bc154d639da4ff2f56c34ef61688e5Ashwin free(mResult); 1826f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng return NL_SKIP; 1827f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng } 1828f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng}; 1829f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1830f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ngwifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num, 1831f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng wifi_passpoint_network *networks, wifi_passpoint_event_handler handler) 1832f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng{ 1833f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng wifi_handle handle = getWifiHandle(iface); 1834f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1835f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng AnqpoConfigureCommand *cmd = new AnqpoConfigureCommand(id, iface, num, networks, handler); 18366af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 18376af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma wifi_error result = wifi_register_cmd(handle, id, cmd); 18386af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma if (result != WIFI_SUCCESS) { 18396af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 18406af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 18416af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma } 18426af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma result = (wifi_error)cmd->start(); 1843a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann if (result != WIFI_SUCCESS) { 1844a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann wifi_unregister_cmd(handle, id); 18456af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma cmd->releaseRef(); 18466af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma return result; 1847a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann } 1848a0a6b2113b44aa39f25635f291fba929c98070bdNavtej Singh Mann return result; 1849f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng} 1850f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng 1851f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ngwifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface) 1852f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng{ 1853fef13c11034313585be68c32322b9a53c43a37b2Ashwin return wifi_cancel_cmd(id, iface); 1854f02e958d58bc49a8f228927dfb261fe57d080560Chilam Ng} 1855