gscan.cpp revision 082cb621b1dd1ad150a747d5010fed0888ae416c
11a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 21a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <stdint.h> 31a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <fcntl.h> 41a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <sys/socket.h> 51a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/genl.h> 61a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/family.h> 71a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/genl/ctrl.h> 81a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/rtnetlink.h> 91a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netpacket/packet.h> 101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/filter.h> 111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/errqueue.h> 121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <linux/pkt_sched.h> 141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/object-api.h> 151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/netlink.h> 161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <netlink/socket.h> 17642bfbe829f5438db3d99ce4678bcb770359a632Vinit Deshpande#include <netlink/handlers.h> 181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "sync.h" 201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#define LOG_TAG "WifiHAL" 221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include <utils/Log.h> 241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "wifi_hal.h" 261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "common.h" 271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde#include "cpp_bindings.h" 281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndetypedef enum { 301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, 321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BASE_PERIOD, 33922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde GSCAN_ATTRIBUTE_BUCKETS_BAND, 341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_ID, 351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_PERIOD, 361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, 371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BUCKET_CHANNELS, 381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, 391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_REPORT_THRESHOLD, 401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, 4127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, 421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, 441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ 451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ 46922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde GSCAN_ENABLE_FULL_SCAN_RESULTS, 47922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde GSCAN_ATTRIBUTE_REPORT_EVENTS, 481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, 511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_FLUSH_RESULTS, 521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ 531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ 541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ 551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ 5627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GSCAN_ATTRIBUTE_NUM_CHANNELS, 5727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GSCAN_ATTRIBUTE_CHANNEL_LIST, 581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SSID = 40, 621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_BSSID, 631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_CHANNEL, 641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI, 651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_TIMESTAMP, 661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RTT, 671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RTTSD, 681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, 721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI_LOW, 731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI_HIGH, 741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_HOTLIST_ELEM, 751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* remaining reserved for additional attributes */ 781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, 791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, 801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_MIN_BREACHING, 811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, 821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GSCAN_ATTRIBUTE_MAX 851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} GSCAN_ATTRIBUTE; 871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 88922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 89922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde// helper methods 90922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_enable_full_scan_results(wifi_request_id id, wifi_interface_handle iface, 91922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler); 92922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface); 93922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 94922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass GetCapabilitiesCommand : public WifiCommand 981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_gscan_capabilities *mCapabilities; 1001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 1011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetCapabilitiesCommand(wifi_interface_handle iface, wifi_gscan_capabilities *capabitlites) 1021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde : WifiCommand(iface, 0), mCapabilities(capabitlites) 1031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { 1041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(mCapabilities, 0, sizeof(*mCapabilities)); 1051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int create() { 1081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id); 1091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CAPABILITIES); 1111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (ret < 0) { 1121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 1131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return ret; 1161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprotected: 1191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 1201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("In GetCapabilities::handleResponse"); 1221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (reply.get_cmd() != NL80211_CMD_VENDOR) { 1241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 1251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 1261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int id = reply.get_vendor_id(); 1291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int subcmd = reply.get_vendor_subcmd(); 1301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde void *data = reply.get_vendor_data(); 1321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = reply.get_vendor_data_len(); 1331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 134e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len, 135e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande sizeof(*mCapabilities)); 136e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande 137e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities))); 1381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_OK; 1401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 1421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, 1451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_gscan_capabilities *capabilities) 1461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetCapabilitiesCommand command(handle, capabilities); 1481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return (wifi_error) command.requestResponse(); 1491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 1501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 15127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinclass GetChannelListCommand : public WifiCommand 15227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin{ 15327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin wifi_channel *channels; 15427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int max_channels; 15527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int *num_channels; 15627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int band; 15727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinpublic: 15827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GetChannelListCommand(wifi_interface_handle iface, wifi_channel *channel_buf, int *ch_num, 15927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int num_max_ch, int band) 16027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin : WifiCommand(iface, 0), channels(channel_buf), max_channels(num_max_ch), num_channels(ch_num), 16127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin band(band) 16227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin { 16327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin memset(channels, 0, sizeof(wifi_channel) * max_channels); 16427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 16527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin virtual int create() { 16627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGD("Creating message to get channel list; iface = %d", mIfaceInfo->id); 16727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 16827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CHANNEL_LIST); 16927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (ret < 0) { 17027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return ret; 17127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 17227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 17327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); 17427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ret = mMsg.put_u32(GSCAN_ATTRIBUTE_BAND, band); 17527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (ret < 0) { 17627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return ret; 17727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 17827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 17927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin mMsg.attr_end(data); 18027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 18127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return ret; 18227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 18327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 18427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinprotected: 18527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin virtual int handleResponse(WifiEvent& reply) { 18627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 18727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGD("In GetChannelList::handleResponse"); 18827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 18927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (reply.get_cmd() != NL80211_CMD_VENDOR) { 19027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 19127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return NL_SKIP; 19227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 19327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 19427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int id = reply.get_vendor_id(); 19527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int subcmd = reply.get_vendor_subcmd(); 19627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int num_channels_to_copy = 0; 19727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 19827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 19927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int len = reply.get_vendor_data_len(); 20027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 20127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 20227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (vendor_data == NULL || len == 0) { 20327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGE("no vendor data in GetChannelList response; ignoring it"); 20427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return NL_SKIP; 20527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 20627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 20727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 20827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if (it.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS) { 20927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin num_channels_to_copy = it.get_u32(); 21027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGI("Got channel list with %d channels", num_channels_to_copy); 21127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if(num_channels_to_copy > max_channels) 21227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin num_channels_to_copy = max_channels; 21327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin *num_channels = num_channels_to_copy; 21427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } else if (it.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST && num_channels_to_copy) { 21527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin memcpy(channels, it.get_data(), sizeof(int) * num_channels_to_copy); 21627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } else { 21727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin ALOGW("Ignoring invalid attribute type = %d, size = %d", 21827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin it.get_type(), it.get_len()); 21927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 22027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 22127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 22227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return NL_OK; 22327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin } 22427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin}; 22527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 22627a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwinwifi_error wifi_get_valid_channels(wifi_interface_handle handle, 22727a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin int band, int max_channels, wifi_channel *channels, int *num_channels) 22827a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin{ 22927a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin GetChannelListCommand command(handle, channels, num_channels, 23027a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin max_channels, band); 23127a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin return (wifi_error) command.requestResponse(); 23227a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin} 2331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 2341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde/* helper functions */ 2361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndestatic int parseScanResults(wifi_scan_result *results, int num, nlattr *attr) 2381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 2391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(results, 0, sizeof(wifi_scan_result) * num); 2401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int i = 0; 2421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it(attr); it.has_next() && i < num; it.next(), i++) { 2431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int index = it.get_type(); 2451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("retrieved scan result %d", index); 2461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *sc_data = (nlattr *) it.get_data(); 2471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result *result = results + i; 2481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it2(sc_data); it2.has_next(); it2.next()) { 2501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int type = it2.get_type(); 2511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (type == GSCAN_ATTRIBUTE_SSID) { 2521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde strncpy(result->ssid, (char *) it2.get_data(), it2.get_len()); 2531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ssid[it2.get_len()] = 0; 2541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_BSSID) { 2551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memcpy(result->bssid, (byte *) it2.get_data(), sizeof(mac_addr)); 2561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_TIMESTAMP) { 2571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ts = it2.get_u64(); 2581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_CHANNEL) { 2591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ts = it2.get_u16(); 2601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_RSSI) { 2611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->rssi = it2.get_u8(); 2621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_RTT) { 2631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->rtt = it2.get_u64(); 2641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (type == GSCAN_ATTRIBUTE_RTTSD) { 2651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->rtt_sd = it2.get_u64(); 2661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (i >= num) { 2721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Got too many results; skipping some"); 2731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return i; 2761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 2771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeint createFeatureRequest(WifiRequest& request, int subcmd, int enable) { 2791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, subcmd); 2811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 2821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 2831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 2861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_ENABLE_FEATURE, enable); 2871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 2881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 2891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 2901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 2921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 2931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 2941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 2951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 296922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndeclass FullScanResultsCommand : public WifiCommand 297922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde{ 298922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int *mParams; 299922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler mHandler; 300922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndepublic: 301922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde FullScanResultsCommand(wifi_interface_handle iface, int id, int *params, 302922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler) 303922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde : WifiCommand(iface, id), mParams(params), mHandler(handler) 304922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde { } 305922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 306922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int createRequest(WifiRequest& request, int subcmd, int enable) { 307922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = request.create(GOOGLE_OUI, subcmd); 308922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 309922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 310922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 311922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 312922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 313922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(GSCAN_ENABLE_FULL_SCAN_RESULTS, enable); 314922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 315922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 316922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 317922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 318922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde request.attr_end(data); 319922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 320922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 321922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 322922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 323922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int start() { 324922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGD("Enabling Full scan results"); 325922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde WifiRequest request(familyId(), ifaceId()); 326922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 1); 327922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 328922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to create request; result = %d", result); 329922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 330922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 331922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 332922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 333922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 334922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = requestResponse(request); 335922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 336922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to enable full scan results; result = %d", result); 337922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 338922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 339922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 340922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 341922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 342922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 343922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 344922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde virtual int cancel() { 345922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGD("Disabling Full scan results"); 346922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 347922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde WifiRequest request(familyId(), ifaceId()); 348922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 0); 349922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 350922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to create request; result = %d", result); 351922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } else { 352922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = requestResponse(request); 353922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 354922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGE("failed to disable full scan results;result = %d", result); 355922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 356922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 357922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 358922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 359922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 360922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 361922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 362922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 363922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGD("Request complete!"); 364922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde /* Nothing to do on response! */ 365922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return NL_SKIP; 366922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 367922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 368922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde virtual int handleEvent(WifiEvent& event) { 369922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("Full scan results: Got an event"); 370922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 371922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde event.log(); 372922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 373922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 374922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde unsigned int len = event.get_vendor_data_len(); 375922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 376922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (vendor_data == NULL || len < sizeof(wifi_scan_result)) { 377922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("No scan results found"); 378922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return NL_SKIP; 379922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 380922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 381922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result *result = (wifi_scan_result *)event.get_vendor_data(); 382922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 38327a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin if(*mHandler.on_full_scan_result) 38427a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin (*mHandler.on_full_scan_result)(id(), result); 38527a89dc4e3256ded710cf7bea77aed3b8cd168e2Ashwin 386922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%-32s\t", result->ssid); 387922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 388922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", result->bssid[0], result->bssid[1], 389922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]); 390922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 391922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%d\t", result->rssi); 392922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%d\t", result->channel); 393922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%lld\t", result->ts); 394922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%lld\t", result->rtt); 395922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("%lld\n", result->rtt_sd); 396922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 397922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 398922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return NL_SKIP; 399922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 400922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 401922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde}; 402922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde///////////////////////////////////////////////////////////////////////////// 4031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass ScanCommand : public WifiCommand 4051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 4061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_cmd_params *mParams; 4071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result_handler mHandler; 408922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde static unsigned mGlobalFullScanBuckets; 409922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde bool mLocalFullScanBuckets; 4101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 4111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params, 4121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result_handler handler) 413922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde : WifiCommand(iface, id), mParams(params), mHandler(handler), 414922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mLocalFullScanBuckets(0) 4151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 4161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createSetupRequest(WifiRequest& request) { 4181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_CONFIG); 4191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 4241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BASE_PERIOD, mParams->base_period); 4251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BUCKETS, mParams->num_buckets); 4301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < mParams->num_buckets; i++) { 4351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr * bucket = request.attr_start(i); // next bucket 4361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID, mParams->buckets[i].bucket); 4371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_PERIOD, mParams->buckets[i].period); 4411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 444922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKETS_BAND, 445922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mParams->buckets[i].band); 446922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 447922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 448922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 449922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 450922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_EVENTS, 451922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mParams->buckets[i].report_events); 452922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 453922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 454922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 455922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 4561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, 4571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mParams->buckets[i].num_channels); 4581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 462922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (mParams->buckets[i].num_channels) { 463922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde nlattr *channels = request.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS); 464922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde for (int j = 0; j < mParams->buckets[i].num_channels; j++) { 465922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = request.put_u32(j, mParams->buckets[i].channels[j].channel); 466922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result < 0) { 467922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 468922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 4691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 470922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde request.attr_end(channels); 4711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(bucket); 4741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 4771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 4781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createScanConfigRequest(WifiRequest& request) { 4811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SCAN_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_NUM_AP_PER_SCAN, mParams->max_ap_per_scan); 4881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 4921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD, mParams->report_threshold); 4931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 4941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 4951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 4961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 497e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int num_scans = 20; 49818d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande for (int i = 0; i < mParams->num_buckets; i++) { 49918d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande if (mParams->buckets[i].report_events == 1) { 50018d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande ALOGD("Setting num_scans to 1"); 50118d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande num_scans = 1; 50218d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande break; 50318d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande } 50418d4cad266ebda5f90092afd7e4f92e72533f637Vinit Deshpande } 50509f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde 50609f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, num_scans); 5071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 5081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 5121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 5131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createStartRequest(WifiRequest& request) { 5161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 5171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createStopRequest(WifiRequest& request) { 5201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0); 5211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 523922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int enableFullScanResultsIfRequired() { 524922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde /* temporary workaround till we have full support for per bucket scans */ 525922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 526922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("enabling full scan results if needed"); 527922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int nBuckets = 0; 528922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde for (int i = 0; i < mParams->num_buckets; i++) { 529922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (mParams->buckets[i].report_events == 2) { 530922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde nBuckets++; 531922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 532922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 533922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 534922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (mGlobalFullScanBuckets == 0 && nBuckets != 0) { 535922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = wifi_enable_full_scan_results(0x1000, ifaceHandle(), mHandler); 536922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 537922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("failed to enable full scan results"); 538922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return result; 539922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } else { 540922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("successfully enabled full scan results"); 541922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 542922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } else { 543922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("mGlobalFullScanBuckets = %d, nBuckets = %d", mGlobalFullScanBuckets, nBuckets); 544922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 545922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 546922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mLocalFullScanBuckets = nBuckets; 547922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mGlobalFullScanBuckets += nBuckets; 548922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 549922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 550922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 551922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int disableFullScanResultsIfRequired() { 552922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde /* temporary workaround till we have full support for per bucket scans */ 553922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 554922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (mLocalFullScanBuckets == 0) { 555922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 556922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 557922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 558922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde mGlobalFullScanBuckets -= mLocalFullScanBuckets; 559922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (mGlobalFullScanBuckets == 0) { 560922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int result = wifi_disable_full_scan_results(0x1000, ifaceHandle()); 561922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (result != WIFI_SUCCESS) { 562922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("failed to disable full scan results"); 563922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } else { 564922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGI("successfully disable full scan results"); 565922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 566922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 567922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 568922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 569922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 570922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 5711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int start() { 5721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Setting configuration"); 5731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 5741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createSetupRequest(request); 5751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 5761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create setup request; result = %d", result); 5771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 5811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 5821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to configure setup; result = %d", result); 5831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.destroy(); 5871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createScanConfigRequest(request); 5891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 5901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create scan config request; result = %d", result); 5911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 5941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 5951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 5961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to configure scan; result = %d", result); 5971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 5981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 5991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Starting scan"); 6011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createStartRequest(request); 6031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create start request; result = %d", result); 6051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 6099a23388d5a9f58f106169700bb179de0a4af7840Ashwin registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 6109a23388d5a9f58f106169700bb179de0a4af7840Ashwin 6111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 6121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to start scan; result = %d", result); 614082cb621b1dd1ad150a747d5010fed0888ae416cVinit Deshpande registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 6151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 6161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 619922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde result = enableFullScanResultsIfRequired(); 6201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 6211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int cancel() { 6241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Stopping scan"); 6251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 6271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createStopRequest(request); 6281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create stop request; result = %d", result); 6301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 6311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 6321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 6331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to stop scan; result = %d", result); 6341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 637082cb621b1dd1ad150a747d5010fed0888ae416cVinit Deshpande unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 6381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 639922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde disableFullScanResultsIfRequired(); 640922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 6411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 6421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 6451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* Nothing to do on response! */ 6461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 6471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleEvent(WifiEvent& event) { 6501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Got a scan results event"); 6511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 65209f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde // event.log(); 6531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 6551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = event.get_vendor_data_len(); 6569a23388d5a9f58f106169700bb179de0a4af7840Ashwin int event_id = event.get_vendor_subcmd(); 6571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6589a23388d5a9f58f106169700bb179de0a4af7840Ashwin if(event_id == GSCAN_EVENT_COMPLETE_SCAN) { 6599a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (vendor_data == NULL || len != 4) { 6609a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGI("Scan complete type not mentioned!"); 6619a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 6629a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 6639a23388d5a9f58f106169700bb179de0a4af7840Ashwin wifi_scan_event evt_type; 6649a23388d5a9f58f106169700bb179de0a4af7840Ashwin 6659a23388d5a9f58f106169700bb179de0a4af7840Ashwin evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA); 6669a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGI("Scan complete: Received event type %d", evt_type); 6679a23388d5a9f58f106169700bb179de0a4af7840Ashwin if(*mHandler.on_scan_event) 6689a23388d5a9f58f106169700bb179de0a4af7840Ashwin (*mHandler.on_scan_event)(evt_type, evt_type); 6699a23388d5a9f58f106169700bb179de0a4af7840Ashwin } else { 6701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6719a23388d5a9f58f106169700bb179de0a4af7840Ashwin if (vendor_data == NULL || len != 4) { 6729a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGI("No scan results found"); 6739a23388d5a9f58f106169700bb179de0a4af7840Ashwin return NL_SKIP; 6749a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 6759a23388d5a9f58f106169700bb179de0a4af7840Ashwin 6769a23388d5a9f58f106169700bb179de0a4af7840Ashwin int num = event.get_u32(NL80211_ATTR_VENDOR_DATA); 6779a23388d5a9f58f106169700bb179de0a4af7840Ashwin ALOGI("Found %d scan results", num); 6789a23388d5a9f58f106169700bb179de0a4af7840Ashwin if(*mHandler.on_scan_results_available) 6799a23388d5a9f58f106169700bb179de0a4af7840Ashwin (*mHandler.on_scan_results_available)(id(), num); 6809a23388d5a9f58f106169700bb179de0a4af7840Ashwin } 6811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 6821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 6831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 6841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 685922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndeunsigned ScanCommand::mGlobalFullScanBuckets = 0; 686922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 6871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_start_gscan( 6881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_request_id id, 6891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_interface_handle iface, 6901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_cmd_params params, 6911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result_handler handler) 6921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 6931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 6941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Starting GScan, halHandle = %p", handle); 6961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 6971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ScanCommand *cmd = new ScanCommand(iface, id, ¶ms, handler); 6981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_register_cmd(handle, id, cmd); 6991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return (wifi_error)cmd->start(); 7001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 7011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface) 7031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 7041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Stopping GScan"); 7051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 7061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 707922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if(id == -1) { 708922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler; 709922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_cmd_params dummy_params; 710922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 711922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde memset(&handler, 0, sizeof(handler)); 712922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 713922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler); 714922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde cmd->cancel(); 71528237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 716922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 717922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 718922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 719922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 7201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiCommand *cmd = wifi_unregister_cmd(handle, id); 7211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd) { 7221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde cmd->cancel(); 72328237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 7241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 7251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 7261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_INVALID_ARGS; 7281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 7291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 730922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 731922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_enable_full_scan_results( 732922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_request_id id, 733922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_interface_handle iface, 734922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler) 735922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde{ 736922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 737922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int params_dummy; 738922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGD("Enabling full scan results, halHandle = %p", handle); 739922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 740922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, ¶ms_dummy, handler); 741922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_register_cmd(handle, id, cmd); 742922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 743922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return (wifi_error)cmd->start(); 744922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde} 745922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 746922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapndewifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface) 747922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde{ 748922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde ALOGD("Disabling full scan results"); 749922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 750922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 751922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if(id == -1) { 752922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_scan_result_handler handler; 753922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde wifi_handle handle = getWifiHandle(iface); 754922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde int params_dummy; 755922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 756922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde memset(&handler, 0, sizeof(handler)); 757922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, 0, ¶ms_dummy, handler); 758922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde cmd->cancel(); 75928237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 760922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 761922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 762922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 763922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde WifiCommand *cmd = wifi_unregister_cmd(handle, id); 764922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde if (cmd) { 765922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde cmd->cancel(); 76628237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 767922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_SUCCESS; 768922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde } 769922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 770922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde return WIFI_ERROR_INVALID_ARGS; 771922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde} 772922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 773922bc148ebc612b6ecf7233b028099aab78feae4Vinit Deshapnde 7741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 7751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass GetScanResultsCommand : public WifiCommand { 7771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result *mResults; 778e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int mMax; 7791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int *mNum; 7801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int mRetrieved; 7811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde byte mFlush; 7821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int mCompleted; 7831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 7841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde GetScanResultsCommand(wifi_interface_handle iface, byte flush, 785e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_scan_result *results, int max, int *num) 786e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande : WifiCommand(iface, -1), mResults(results), mMax(max), mNum(num), 7871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mRetrieved(0), mFlush(flush), mCompleted(0) 7881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 7891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createRequest(WifiRequest& request, int num, byte flush) { 7911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_SCAN_RESULTS); 7921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 7931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 7941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 7951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 7961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 7971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u32(GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num); 7981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 7991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_FLUSH_RESULTS, flush); 8031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 8041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 8081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 8091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int execute() { 8121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 813e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande ALOGI("retrieving %d scan results", mMax); 8141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 815e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande for (int i = 0; i < 10 && mRetrieved < mMax; i++) { 816e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int result = createRequest(request, (mMax - mRetrieved), mFlush); 8171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 8181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to create request"); 8191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int prev_retrieved = mRetrieved; 8231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 8251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result != WIFI_SUCCESS) { 8271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("failed to retrieve scan results; result = %d", result); 8281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 8291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (mRetrieved == prev_retrieved || mCompleted) { 8321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* no more items left to retrieve */ 8331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde break; 8341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.destroy(); 8371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("GetScanResults read %d results", mRetrieved); 8401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde *mNum = mRetrieved; 8411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 8421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 8451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("In GetScanResultsCommand::handleResponse"); 8461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (reply.get_cmd() != NL80211_CMD_VENDOR) { 8481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 8491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 8501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int id = reply.get_vendor_id(); 8531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int subcmd = reply.get_vendor_subcmd(); 8541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Id = %0x, subcmd = %d", id, subcmd); 8561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* 8581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (subcmd != GSCAN_SUBCMD_SCAN_RESULTS) { 8591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("Invalid response to GetScanResultsCommand; ignoring it"); 8601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 8611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde */ 8631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 8651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = reply.get_vendor_data_len(); 8661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (vendor_data == NULL || len == 0) { 8681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGE("no vendor data in GetScanResults response; ignoring it"); 8691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 8701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 8721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 8731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE) { 8741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mCompleted = it.get_u8(); 8751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("retrieved mCompleted flag : %d", mCompleted); 8761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS || it.get_type() == 0) { 8771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) { 8781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int scan_id = 0, flags = 0, num = 0; 8791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) { 8801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde scan_id = it.get_u32(); 8811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS) { 8821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde flags = it.get_u8(); 8831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { 8841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde num = it2.get_u32(); 8851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS) { 8861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde num = it2.get_len() / sizeof(wifi_scan_result); 8871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde num = min(*mNum - mRetrieved, num); 8881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memcpy(mResults + mRetrieved, it2.get_data(), 8891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde sizeof(wifi_scan_result) * num); 8901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Retrieved %d scan results", num); 8911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result *results = (wifi_scan_result *)it2.get_data(); 8921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < num; i++) { 8931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result *result = results + i; 89409f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde ALOGI("%02d %-32s %02x:%02x:%02x:%02x:%02x:%02x %04d", i, 8951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result->ssid, result->bssid[0], result->bssid[1], result->bssid[2], 89609f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde result->bssid[3], result->bssid[4], result->bssid[5], 89709f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde result->rssi); 8981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 8991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mRetrieved += num; 9001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 9011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGW("Ignoring invalid attribute type = %d, size = %d", 9021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde it.get_type(), it.get_len()); 9031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 9061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGW("Ignoring invalid attribute type = %d, size = %d", 9071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde it.get_type(), it.get_len()); 9081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_OK; 9121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 9141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush, 916e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int max, wifi_scan_result *results, int *num) { 9171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGD("Getting cached scan results, iface handle = %p, num = %d", iface, *num); 9191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 920e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num); 9211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return (wifi_error)cmd->execute(); 9221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 9231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 9251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass BssidHotlistCommand : public WifiCommand 9271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 9281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprivate: 9291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_bssid_hotlist_params mParams; 9301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_hotlist_ap_found_handler mHandler; 9311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde static const int MAX_RESULTS = 64; 9321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_scan_result mResults[MAX_RESULTS]; 9331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 9341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde BssidHotlistCommand(wifi_interface_handle handle, int id, 9351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) 9361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde : WifiCommand(handle, id), mParams(params), mHandler(handler) 9371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 9381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createSetupRequest(WifiRequest& request) { 9401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST); 9411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 9461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1); 9471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS); 952e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande for (int i = 0; i < mParams.num_ap; i++) { 9531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *attr2 = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_ELEM); 9541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (attr2 == NULL) { 9551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_OUT_OF_MEMORY; 9561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 957e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid); 9581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 961e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high); 9621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 965e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low); 9661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr2); 9701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr); 9731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 9741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createTeardownRequest(WifiRequest& request) { 9781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST); 9791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 9841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1); 9851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 9861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS); 9901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr); 9911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 9921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 9931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 9941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 9951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int start() { 996e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande ALOGI("Executing hotlist setup request, num = %d", mParams.num_ap); 9971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 9981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createSetupRequest(request); 9991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 10041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Failed to execute hotlist setup request, result = %d", result); 10061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS); 10071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1010e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande ALOGI("Successfully set %d APs in the hotlist", mParams.num_ap); 10111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 10121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS); 10171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 10191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS); 10211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully restarted the scan"); 10251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int cancel() { 10291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* unregister event handler */ 10301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS); 10311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* create set hotlist message with empty hotlist */ 10331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 10341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createTeardownRequest(request); 10351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 10401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 10411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Successfully reset APs in current hotlist"); 10451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 10461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 10491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* Nothing to do on response! */ 10501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 10511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleEvent(WifiEvent& event) { 10541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Got a hotlist ap found event"); 10551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 105609f45268753c6021b621e0be82a6808cebbaa37dVinit Deshapnde // event.log(); 10571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 10591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = event.get_vendor_data_len(); 10601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (vendor_data == NULL || len == 0) { 10621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("No scan results found"); 10631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 10641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS); 10671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int num = len / sizeof(wifi_scan_result); 10691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde num = min(MAX_RESULTS, num); 10701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde memcpy(mResults, event.get_vendor_data(), num * sizeof(wifi_scan_result)); 10711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Retrieved %d hot APs", num); 10721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde (*mHandler.on_hotlist_ap_found)(id(), num, mResults); 10741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 10751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 10771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface, 10791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) 10801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 10811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 10821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler); 10841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_register_cmd(handle, id, cmd); 10851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return (wifi_error)cmd->start(); 10861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 10871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface) 10891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 10901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 10911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiCommand *cmd = wifi_unregister_cmd(handle, id); 10931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd) { 10941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde cmd->cancel(); 109528237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 10961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 10971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 10981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 10991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_INVALID_ARGS; 11001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 11011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde///////////////////////////////////////////////////////////////////////////// 11041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeclass SignificantWifiChangeCommand : public WifiCommand 11061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 1107e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande typedef struct { 1108e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mac_addr bssid; // BSSID 1109e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_channel channel; // channel frequency in MHz 1110e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande int num_rssi; // number of rssi samples 1111e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_rssi rssi[8]; // RSSI history in db 1112e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande } wifi_significant_change_result_internal; 1113e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande 11141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndeprivate: 11151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_params mParams; 11161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_handler mHandler; 11171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde static const int MAX_RESULTS = 64; 1118e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_significant_change_result_internal mResultsBuffer[MAX_RESULTS]; 1119e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande wifi_significant_change_result *mResults[MAX_RESULTS]; 11201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndepublic: 11211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde SignificantWifiChangeCommand(wifi_interface_handle handle, int id, 11221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_params params, wifi_significant_change_handler handler) 11231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde : WifiCommand(handle, id), mParams(params), mHandler(handler) 11241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde { } 11251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createSetupRequest(WifiRequest& request) { 11271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); 11281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 11331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u8(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1); 11341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE, mParams.rssi_sample_size); 11381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size); 11421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_MIN_BREACHING, mParams.min_breaching); 11461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS); 11511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 1152e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande for (int i = 0; i < mParams.num_ap; i++) { 11531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *attr2 = request.attr_start(i); 11551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (attr2 == NULL) { 11561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_OUT_OF_MEMORY; 11571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1158e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid); 11591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1162e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high); 11631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 1166e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low); 11671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11701a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr2); 11711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(attr); 11741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 11751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11771a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11781a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11791a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int createTeardownRequest(WifiRequest& request) { 11801a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); 11811a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11821a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 11861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = request.put_u16(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1); 11871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 11881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde request.attr_end(data); 11921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 11931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 11941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int start() { 11961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Set significant wifi change config"); 11971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 11981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 11991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createSetupRequest(request); 12001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 12011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 12051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 12061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("failed to set significant wifi change config %d", result); 12071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully set significant wifi change config"); 12111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 12131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 12141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12151a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 12181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 12201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 12211a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 12221a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12231a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12241a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12251a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully restarted the scan"); 12261a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12271a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12281a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12291a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int cancel() { 12301a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* unregister event handler */ 12311a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 12321a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12331a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* create set significant change monitor message with empty hotlist */ 12341a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiRequest request(familyId(), ifaceId()); 12351a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12361a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int result = createTeardownRequest(request); 12371a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 12381a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12391a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12401a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12411a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde result = requestResponse(request); 12421a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (result < 0) { 12431a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12441a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12451a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12461a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("successfully reset significant wifi change config"); 12471a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return result; 12481a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12491a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12501a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleResponse(WifiEvent& reply) { 12511a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde /* Nothing to do on response! */ 12521a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 12531a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12541a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12551a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde virtual int handleEvent(WifiEvent& event) { 12561a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Got a significant wifi change event"); 12571a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12581a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 12591a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int len = event.get_vendor_data_len(); 12601a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12611a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (vendor_data == NULL || len == 0) { 12621a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("No scan results found"); 12631a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 12641a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12651a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12661a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde typedef struct { 12671a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde uint16_t flags; 12681a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde uint16_t channel; 12691a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde mac_addr bssid; 12709a23388d5a9f58f106169700bb179de0a4af7840Ashwin s8 rssi_history[8]; 12711a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } ChangeInfo; 12721a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12731a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde int num = min(len / sizeof(ChangeInfo), MAX_RESULTS); 12741a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ChangeInfo *ci = (ChangeInfo *)event.get_vendor_data(); 12751a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12761a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde for (int i = 0; i < num; i++) { 1277e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande memcpy(mResultsBuffer[i].bssid, ci[i].bssid, sizeof(mac_addr)); 1278e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mResultsBuffer[i].channel = ci[i].channel; 1279e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mResultsBuffer[i].num_rssi = 8; 12809a23388d5a9f58f106169700bb179de0a4af7840Ashwin for (int j = 0; j < mResultsBuffer[i].num_rssi; j++) 12819a23388d5a9f58f106169700bb179de0a4af7840Ashwin mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j]; 1282e165f3a9d7d77eed0ae55bebf885d9a879a9349cVinit Deshpande mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i])); 12831a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12841a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12851a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGI("Retrieved %d scan results", num); 12861a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12871a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (num != 0) { 12881a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde (*mHandler.on_significant_change)(id(), num, mResults); 12891a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } else { 12901a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde ALOGW("No significant change reported"); 12911a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12921a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12931a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return NL_SKIP; 12941a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 12951a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde}; 12961a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 12971a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface, 12981a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_significant_change_params params, wifi_significant_change_handler handler) 12991a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 13001a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 13011a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 13021a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand( 13031a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde iface, id, params, handler); 13041a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_register_cmd(handle, id, cmd); 13051a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return (wifi_error)cmd->start(); 13061a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 13071a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 13081a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapndewifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface) 13091a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde{ 13101a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde wifi_handle handle = getWifiHandle(iface); 13111a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 13121a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde WifiCommand *cmd = wifi_unregister_cmd(handle, id); 13131a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde if (cmd) { 13141a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde cmd->cancel(); 131528237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 13161a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_SUCCESS; 13171a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde } 13181a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde 13191a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde return WIFI_ERROR_INVALID_ARGS; 13201a526434ae215b48970501ccb463d4e77af39c9eVinit Deshapnde} 1321