1115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <stdint.h> 2115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <fcntl.h> 3115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <sys/socket.h> 4115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/genl/genl.h> 5115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/genl/family.h> 6115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/genl/ctrl.h> 7115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/rtnetlink.h> 8115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netpacket/packet.h> 9115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/filter.h> 10115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/errqueue.h> 11115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 12115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/pkt_sched.h> 13115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/object-api.h> 14115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/netlink.h> 15115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/socket.h> 16115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink-types.h> 17115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 18115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "nl80211_copy.h" 19115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 20115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "sync.h" 21115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 22115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#define LOG_TAG "WifiHAL" 23115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 24115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <utils/Log.h> 25115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 26115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "wifi_hal.h" 27115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "common.h" 28115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "cpp_bindings.h" 29115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 30115bcffc16c53e9552c09a6792666c52a633b4f2Ashwintypedef enum { 31115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 323acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, 333acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park RTT_SUBCMD_CANCEL_CONFIG, 343acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park RTT_SUBCMD_GETCAPABILITY, 35115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin} RTT_SUB_COMMAND; 36115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 37115bcffc16c53e9552c09a6792666c52a633b4f2Ashwintypedef enum { 38115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_CNT, 39115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_INFO, 40115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_MAC, 41115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_TYPE, 42115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_PEER, 43115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_CHAN, 44115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_MODE, 45115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_INTERVAL, 46115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT, 47115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_NUM_PKT, 48115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RTT_ATTRIBUTE_TARGET_NUM_RETRY, 493acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 50115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin} GSCAN_ATTRIBUTE; 513acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkclass GetRttCapabilitiesCommand : public WifiCommand 523acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park{ 533acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park wifi_rtt_capabilities *mCapabilities; 543acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkpublic: 553acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites) 563acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park : WifiCommand(iface, 0), mCapabilities(capabitlites) 573acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park { 583acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park memset(mCapabilities, 0, sizeof(*mCapabilities)); 593acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park } 603acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 613acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park virtual int create() { 623acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id); 633acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 643acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETCAPABILITY); 653acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park if (ret < 0) { 663acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park return ret; 673acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park } 683acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 693acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park return ret; 703acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park } 713acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 723acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkprotected: 733acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park virtual int handleResponse(WifiEvent& reply) { 743acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 753acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park ALOGD("In GetRttCapabilitiesCommand::handleResponse"); 763acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 773acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park if (reply.get_cmd() != NL80211_CMD_VENDOR) { 783acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 793acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park return NL_SKIP; 803acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park } 813acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 823acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park int id = reply.get_vendor_id(); 833acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park int subcmd = reply.get_vendor_subcmd(); 843acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 853acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park void *data = reply.get_vendor_data(); 863acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park int len = reply.get_vendor_data_len(); 873acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 883acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len, 893acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park sizeof(*mCapabilities)); 903acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 913acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities))); 923acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park 933acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park return NL_OK; 943acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park } 953acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park}; 96115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 97115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 98115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinclass RttCommand : public WifiCommand 99115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin{ 100115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin unsigned numRttParams; 101115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin static const int MAX_RESULTS = 64; 102115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_rtt_result rttResults[MAX_RESULTS]; 103115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_rtt_config *rttParams; 104115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_rtt_event_handler rttHandler; 105115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinpublic: 106115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config, 107115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler) 108115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin : WifiCommand(iface, id), numRttParams(num_rtt_config), rttParams(rtt_config), 109115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin rttHandler(handler) 110115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin { } 111115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 112115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 113115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int createSetupRequest(WifiRequest& request) { 114115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int result = request.create(GOOGLE_OUI, RTT_SUBCMD_SET_CONFIG); 115115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 116115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 117115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 118115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 119115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 120115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, numRttParams); 121115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 122115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 123115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 124115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO); 125115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin for (unsigned i = 0; i < numRttParams; i++) { 126115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 127115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin nlattr *attr2 = request.attr_start(i); 128115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (attr2 == NULL) { 129115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return WIFI_ERROR_OUT_OF_MEMORY; 130115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 131115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 132115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr); 133115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 134115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 135115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 136115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type); 137115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 138115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 139115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 140115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer); 141115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 142115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 143115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 144115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel, 145115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin sizeof(wifi_channel_info)); 146115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 147115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 148115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 149115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u8(RTT_ATTRIBUTE_TARGET_MODE, rttParams[i].continuous); 150115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 151115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 152115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 153115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u32(RTT_ATTRIBUTE_TARGET_INTERVAL, rttParams[i].interval); 154115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 155115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 156115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 157115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT, 158115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin rttParams[i].num_measurements); 159115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 160115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 161115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 162115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_PKT, 163115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin rttParams[i].num_samples_per_measurement); 164115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 165115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 166115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 167115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY, 168115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin rttParams[i].num_retries_per_measurement); 169115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 170115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 171115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 172115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin request.attr_end(attr2); 173115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 174115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 175115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin request.attr_end(rtt_config); 176115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin request.attr_end(data); 177115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return WIFI_SUCCESS; 178115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 179115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 180115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int createTeardownRequest(WifiRequest& request, unsigned num_devices, mac_addr addr[]) { 1813acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park int result = request.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_CONFIG); 182115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 183115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 184115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 185115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 186115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1873acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices); 188115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin for(unsigned i = 0; i < num_devices; i++) { 189115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]); 190115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result < 0) { 191115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 192115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 193115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 194115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin request.attr_end(data); 195115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 196115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 197115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int start() { 19868d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande ALOGD("Setting RTT configuration"); 199115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin WifiRequest request(familyId(), ifaceId()); 200115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int result = createSetupRequest(request); 201115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result != WIFI_SUCCESS) { 202115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGE("failed to create setup request; result = %d", result); 203115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 204115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 205115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 206115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = requestResponse(request); 207115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result != WIFI_SUCCESS) { 20868d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande ALOGE("failed to configure RTT setup; result = %d", result); 209115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 210115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 211115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 212115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); 21368d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande ALOGI("Successfully started RTT operation"); 214115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return result; 215115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 216115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 217115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin virtual int cancel() { 21868d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande ALOGD("Stopping RTT"); 219115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 220115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin WifiRequest request(familyId(), ifaceId()); 221115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int result = createTeardownRequest(request, 0, NULL); 222115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result != WIFI_SUCCESS) { 223115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGE("failed to create stop request; result = %d", result); 224115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } else { 225115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = requestResponse(request); 226115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result != WIFI_SUCCESS) { 227115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGE("failed to stop scan; result = %d", result); 228115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 229115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 230115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 23168d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); 232115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return WIFI_SUCCESS; 233115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 234115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 235115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int cancel_specific(unsigned num_devices, mac_addr addr[]) { 236115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGD("Stopping scan"); 237115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 238115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin WifiRequest request(familyId(), ifaceId()); 239115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int result = createTeardownRequest(request, num_devices, addr); 240115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result != WIFI_SUCCESS) { 241115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGE("failed to create stop request; result = %d", result); 242115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } else { 243115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin result = requestResponse(request); 244115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (result != WIFI_SUCCESS) { 24568d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande ALOGE("failed to stop RTT; result = %d", result); 246115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 247115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 248115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 24968d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); 250115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return WIFI_SUCCESS; 251115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 252115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 253115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin virtual int handleResponse(WifiEvent& reply) { 254115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin /* Nothing to do on response! */ 255115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return NL_SKIP; 256115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 257115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 258115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin virtual int handleEvent(WifiEvent& event) { 259732e4dd91aebbfb225feaed05893e2ec76842a10Vinit Deshpande ALOGI("Got an RTT event"); 260115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 261115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin // event.log(); 262115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 263115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 264115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int len = event.get_vendor_data_len(); 265115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 266115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (vendor_data == NULL || len == 0) { 267115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGI("No rtt results found"); 268115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 269115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 27068d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); 27168d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande wifi_unregister_cmd(wifiHandle(), id()); 27268d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande 273115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin memset(rttResults, 0, sizeof(wifi_rtt_result) * MAX_RESULTS); 274115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 275115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin int num = len / sizeof(wifi_rtt_result); 276115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin num = min(MAX_RESULTS, num); 277115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin memcpy(rttResults, event.get_vendor_data(), num * sizeof(wifi_rtt_result)); 278115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin ALOGI("Retrieved %d rtt results", num); 279115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 280115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin (*rttHandler.on_rtt_results)(id(), num, rttResults); 281115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return NL_SKIP; 282115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 283115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin}; 284115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 285115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 286115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin/* API to request RTT measurement */ 287115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinwifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface, 288115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler) 289115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin{ 290115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_handle handle = getWifiHandle(iface); 291115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 292115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler); 293115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_register_cmd(handle, id, cmd); 294115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return (wifi_error)cmd->start(); 295115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin} 296115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 297115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin/* API to cancel RTT measurements */ 298115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinwifi_error wifi_rtt_range_cancel(wifi_request_id id, wifi_interface_handle iface, 299115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin unsigned num_devices, mac_addr addr[]) 300115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin{ 301115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin wifi_handle handle = getWifiHandle(iface); 3023acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park RttCommand *cmd = (RttCommand *)wifi_unregister_cmd(handle, id); 303115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin if (cmd) { 304115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin cmd->cancel_specific(num_devices, addr); 30528237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande cmd->releaseRef(); 306115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return WIFI_SUCCESS; 307115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin } 308115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 309115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin return WIFI_ERROR_INVALID_ARGS; 310115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin} 31128237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande 3123acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park/* API to get RTT capability */ 3133acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkwifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface, 3143acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park wifi_rtt_capabilities *capabilities) 3153acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park{ 3163acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park GetRttCapabilitiesCommand command(iface, capabilities); 3173acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park return (wifi_error) command.requestResponse(); 3183acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park} 319115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 320115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin 321