1cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song/*
2cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Copyright (C) 2017 The Android Open Source Project
3cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song *
4cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Portions copyright (C) 2017 Broadcom Limited
5cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song *
6cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Licensed under the Apache License, Version 2.0 (the "License");
7cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * you may not use this file except in compliance with the License.
8cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * You may obtain a copy of the License at
9cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song *
10cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song *     http://www.apache.org/licenses/LICENSE-2.0
11cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song *
12cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * Unless required by applicable law or agreed to in writing, software
13cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * distributed under the License is distributed on an "AS IS" BASIS,
14cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * See the License for the specific language governing permissions and
16cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song * limitations under the License.
17cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song */
18cb8188ea5d3dbce3bf46522bc9e562ffa04db2e7Insun Song
19115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <stdint.h>
20115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <fcntl.h>
21115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <sys/socket.h>
22115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/genl/genl.h>
23115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/genl/family.h>
24115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/genl/ctrl.h>
25115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/rtnetlink.h>
26115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netpacket/packet.h>
27115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/filter.h>
28115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/errqueue.h>
29115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
30115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <linux/pkt_sched.h>
31115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/object-api.h>
32115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/netlink.h>
33115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include <netlink/socket.h>
34c4ca0d79752e6262b0800c971ea2b4bb6d4e0c58Paul Stewart#include <netlink-private/object-api.h>
35c4ca0d79752e6262b0800c971ea2b4bb6d4e0c58Paul Stewart#include <netlink-private/types.h>
36115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
37115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "nl80211_copy.h"
38115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
39115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "sync.h"
40115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
41115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#define LOG_TAG  "WifiHAL"
42115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
43f05bfb019590f8e25471c0fae23db519dfcfb790Pierre Couillaud#include <log/log.h>
44215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#include <utils/String8.h>
45115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
46115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "wifi_hal.h"
47115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "common.h"
48115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin#include "cpp_bindings.h"
49115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
50215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.comusing namespace android;
51215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#define RTT_RESULT_SIZE (sizeof(wifi_rtt_result));
52115bcffc16c53e9552c09a6792666c52a633b4f2Ashwintypedef enum {
53115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
543acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
553acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    RTT_SUBCMD_CANCEL_CONFIG,
563acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    RTT_SUBCMD_GETCAPABILITY,
5789b86262c90552a05a6177944d0ced6b01f27d80gautam    RTT_SUBCMD_GETAVAILCHANNEL,
5889b86262c90552a05a6177944d0ced6b01f27d80gautam    RTT_SUBCMD_SET_RESPONDER,
5989b86262c90552a05a6177944d0ced6b01f27d80gautam    RTT_SUBCMD_CANCEL_RESPONDER,
60115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin} RTT_SUB_COMMAND;
61115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
62115bcffc16c53e9552c09a6792666c52a633b4f2Ashwintypedef enum {
63215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_CNT = 0,
64115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RTT_ATTRIBUTE_TARGET_INFO,
65115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RTT_ATTRIBUTE_TARGET_MAC,
66115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RTT_ATTRIBUTE_TARGET_TYPE,
67115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RTT_ATTRIBUTE_TARGET_PEER,
68115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RTT_ATTRIBUTE_TARGET_CHAN,
69abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_PERIOD,
70215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_NUM_BURST,
71215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
72215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
73215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
74215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_LCI,
75215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_LCR,
76abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_BURST_DURATION,
77215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_PREAMBLE,
78215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_TARGET_BW,
79215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
80215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_RESULTS_PER_TARGET,
81215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_RESULT_CNT,
82215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    RTT_ATTRIBUTE_RESULT
83215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com} RTT_ATTRIBUTE;
84215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.comtypedef struct strmap_entry {
85215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    int			id;
86215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    String8		text;
87215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com} strmap_entry_t;
88215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.comstruct dot11_rm_ie {
89215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    u8 id;
90215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    u8 len;
91215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    u8 token;
92215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    u8 mode;
93215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    u8 type;
94215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com} __attribute__ ((packed));
95215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.comtypedef struct dot11_rm_ie dot11_rm_ie_t;
96215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#define DOT11_HDR_LEN 2
97215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#define DOT11_RM_IE_LEN       5
98215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#define DOT11_MNG_MEASURE_REQUEST_ID		38	/* 11H MeasurementRequest */
99215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#define DOT11_MEASURE_TYPE_LCI		8   /* d11 measurement LCI type */
100215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com#define DOT11_MEASURE_TYPE_CIVICLOC	11  /* d11 measurement location civic */
101215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
102215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.comstatic const strmap_entry_t err_info[] = {
103215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_SUCCESS, String8("Success")},
104215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAILURE, String8("Failure")},
105215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_NO_RSP, String8("No reponse")},
106215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_INVALID_TS, String8("Invalid Timestamp")},
107215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_PROTOCOL, String8("Protocol error")},
108215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_REJECTED, String8("Rejected")},
109215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_NOT_SCHEDULED_YET, String8("not scheduled")},
110215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_SCHEDULE,  String8("schedule failed")},
111215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_TM_TIMEOUT, String8("timeout")},
112215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, String8("AP is on difference channel")},
113215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_NO_CAPABILITY, String8("no capability")},
114215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_FAIL_BUSY_TRY_LATER, String8("busy and try later")},
115215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {RTT_STATUS_ABORTED, String8("aborted")}
116215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com};
117215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
118215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    static const char*
119215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.comget_err_info(int status)
120215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com{
121215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    int i;
122215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    const strmap_entry_t *p_entry;
123215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
124215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    /* scan thru the table till end */
125215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    p_entry = err_info;
126215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    for (i = 0; i < (int) num_entries; i++)
127215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {
128215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        if (p_entry->id == status)
129215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            return p_entry->text;
130215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        p_entry++;		/* next entry */
131215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    }
132215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    return "unknown error";			/* not found */
133215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com}
1343acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1353acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkclass GetRttCapabilitiesCommand : public WifiCommand
1363acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park{
1373acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    wifi_rtt_capabilities *mCapabilities;
1383acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkpublic:
1393acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites)
140d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande        : WifiCommand("GetRttCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
1413acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    {
1423acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        memset(mCapabilities, 0, sizeof(*mCapabilities));
1433acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    }
1443acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1453acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    virtual int create() {
1463acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
1473acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1483acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETCAPABILITY);
1493acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        if (ret < 0) {
1503acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park            return ret;
1513acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        }
1523acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1533acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        return ret;
1543acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    }
1553acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1563acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkprotected:
1573acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    virtual int handleResponse(WifiEvent& reply) {
1583acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1593acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        ALOGD("In GetRttCapabilitiesCommand::handleResponse");
1603acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1613acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
1623acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
1633acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park            return NL_SKIP;
1643acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        }
1653acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1663acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        int id = reply.get_vendor_id();
1673acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        int subcmd = reply.get_vendor_subcmd();
1683acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1693acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        void *data = reply.get_vendor_data();
1703acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        int len = reply.get_vendor_data_len();
1713acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1723acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
173215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                sizeof(*mCapabilities));
1743acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1753acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
1763acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park
1773acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        return NL_OK;
1783acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    }
1793acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park};
180115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
181115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
182d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautamclass GetRttResponderInfoCommand : public WifiCommand
18389b86262c90552a05a6177944d0ced6b01f27d80gautam{
184d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam    wifi_rtt_responder* mResponderInfo;
18589b86262c90552a05a6177944d0ced6b01f27d80gautampublic:
186d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam    GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
187d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam        : WifiCommand("GetRttResponderInfoCommand", iface, 0), mResponderInfo(responderInfo)
18889b86262c90552a05a6177944d0ced6b01f27d80gautam    {
189d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam        memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
19089b86262c90552a05a6177944d0ced6b01f27d80gautam
19189b86262c90552a05a6177944d0ced6b01f27d80gautam    }
19289b86262c90552a05a6177944d0ced6b01f27d80gautam
19389b86262c90552a05a6177944d0ced6b01f27d80gautam    virtual int create() {
194d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam        ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
19589b86262c90552a05a6177944d0ced6b01f27d80gautam
19689b86262c90552a05a6177944d0ced6b01f27d80gautam        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETAVAILCHANNEL);
19789b86262c90552a05a6177944d0ced6b01f27d80gautam        if (ret < 0) {
19889b86262c90552a05a6177944d0ced6b01f27d80gautam            return ret;
19989b86262c90552a05a6177944d0ced6b01f27d80gautam        }
20089b86262c90552a05a6177944d0ced6b01f27d80gautam
20189b86262c90552a05a6177944d0ced6b01f27d80gautam        return ret;
20289b86262c90552a05a6177944d0ced6b01f27d80gautam    }
20389b86262c90552a05a6177944d0ced6b01f27d80gautam
20489b86262c90552a05a6177944d0ced6b01f27d80gautamprotected:
20589b86262c90552a05a6177944d0ced6b01f27d80gautam    virtual int handleResponse(WifiEvent& reply) {
20689b86262c90552a05a6177944d0ced6b01f27d80gautam
207d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam        ALOGD("In GetRttResponderInfoCommand::handleResponse");
20889b86262c90552a05a6177944d0ced6b01f27d80gautam
20989b86262c90552a05a6177944d0ced6b01f27d80gautam        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
21089b86262c90552a05a6177944d0ced6b01f27d80gautam            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
21189b86262c90552a05a6177944d0ced6b01f27d80gautam            return NL_SKIP;
21289b86262c90552a05a6177944d0ced6b01f27d80gautam        }
21389b86262c90552a05a6177944d0ced6b01f27d80gautam
21489b86262c90552a05a6177944d0ced6b01f27d80gautam        int id = reply.get_vendor_id();
21589b86262c90552a05a6177944d0ced6b01f27d80gautam        int subcmd = reply.get_vendor_subcmd();
21689b86262c90552a05a6177944d0ced6b01f27d80gautam
21789b86262c90552a05a6177944d0ced6b01f27d80gautam        void *data = reply.get_vendor_data();
21889b86262c90552a05a6177944d0ced6b01f27d80gautam        int len = reply.get_vendor_data_len();
21989b86262c90552a05a6177944d0ced6b01f27d80gautam
22089b86262c90552a05a6177944d0ced6b01f27d80gautam        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
221d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam                sizeof(*mResponderInfo));
22289b86262c90552a05a6177944d0ced6b01f27d80gautam
223c15e33f73c7cf61a3491bc81dc46fe9e5a0f051cWei Wang        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
22489b86262c90552a05a6177944d0ced6b01f27d80gautam
22589b86262c90552a05a6177944d0ced6b01f27d80gautam        return NL_OK;
22689b86262c90552a05a6177944d0ced6b01f27d80gautam    }
22789b86262c90552a05a6177944d0ced6b01f27d80gautam};
22889b86262c90552a05a6177944d0ced6b01f27d80gautam
22989b86262c90552a05a6177944d0ced6b01f27d80gautam
23089b86262c90552a05a6177944d0ced6b01f27d80gautamclass EnableResponderCommand : public WifiCommand
23189b86262c90552a05a6177944d0ced6b01f27d80gautam{
23289b86262c90552a05a6177944d0ced6b01f27d80gautam    wifi_channel_info  mChannelInfo;
233d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam    wifi_rtt_responder* mResponderInfo;
23489b86262c90552a05a6177944d0ced6b01f27d80gautam    unsigned m_max_duration_sec;
23589b86262c90552a05a6177944d0ced6b01f27d80gautampublic:
23689b86262c90552a05a6177944d0ced6b01f27d80gautam    EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
237d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam            unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
23889b86262c90552a05a6177944d0ced6b01f27d80gautam            : WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
239d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam            m_max_duration_sec(max_duration_seconds), mResponderInfo(responderInfo)
24089b86262c90552a05a6177944d0ced6b01f27d80gautam    {
2416af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma        memset(mResponderInfo, 0, sizeof(*mResponderInfo));
24289b86262c90552a05a6177944d0ced6b01f27d80gautam    }
24389b86262c90552a05a6177944d0ced6b01f27d80gautam
24489b86262c90552a05a6177944d0ced6b01f27d80gautam    virtual int create() {
24589b86262c90552a05a6177944d0ced6b01f27d80gautam        ALOGD("Creating message to set responder ; iface = %d", mIfaceInfo->id);
24689b86262c90552a05a6177944d0ced6b01f27d80gautam
24789b86262c90552a05a6177944d0ced6b01f27d80gautam        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_SET_RESPONDER);
24889b86262c90552a05a6177944d0ced6b01f27d80gautam        if (ret < 0) {
24989b86262c90552a05a6177944d0ced6b01f27d80gautam            return ret;
25089b86262c90552a05a6177944d0ced6b01f27d80gautam        }
25189b86262c90552a05a6177944d0ced6b01f27d80gautam
25289b86262c90552a05a6177944d0ced6b01f27d80gautam        return ret;
25389b86262c90552a05a6177944d0ced6b01f27d80gautam    }
25489b86262c90552a05a6177944d0ced6b01f27d80gautam
25589b86262c90552a05a6177944d0ced6b01f27d80gautamprotected:
25689b86262c90552a05a6177944d0ced6b01f27d80gautam    virtual int handleResponse(WifiEvent& reply) {
25789b86262c90552a05a6177944d0ced6b01f27d80gautam
25889b86262c90552a05a6177944d0ced6b01f27d80gautam        ALOGD("In EnableResponderCommand::handleResponse");
25989b86262c90552a05a6177944d0ced6b01f27d80gautam
26089b86262c90552a05a6177944d0ced6b01f27d80gautam        if (reply.get_cmd() != NL80211_CMD_VENDOR) {
26189b86262c90552a05a6177944d0ced6b01f27d80gautam            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
26289b86262c90552a05a6177944d0ced6b01f27d80gautam            return NL_SKIP;
26389b86262c90552a05a6177944d0ced6b01f27d80gautam        }
26489b86262c90552a05a6177944d0ced6b01f27d80gautam
26589b86262c90552a05a6177944d0ced6b01f27d80gautam        int id = reply.get_vendor_id();
26689b86262c90552a05a6177944d0ced6b01f27d80gautam        int subcmd = reply.get_vendor_subcmd();
26789b86262c90552a05a6177944d0ced6b01f27d80gautam
26889b86262c90552a05a6177944d0ced6b01f27d80gautam        void *data = reply.get_vendor_data();
26989b86262c90552a05a6177944d0ced6b01f27d80gautam        int len = reply.get_vendor_data_len();
27089b86262c90552a05a6177944d0ced6b01f27d80gautam
27189b86262c90552a05a6177944d0ced6b01f27d80gautam        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
272d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam                sizeof(*mResponderInfo));
27389b86262c90552a05a6177944d0ced6b01f27d80gautam
274c15e33f73c7cf61a3491bc81dc46fe9e5a0f051cWei Wang        memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
27589b86262c90552a05a6177944d0ced6b01f27d80gautam
27689b86262c90552a05a6177944d0ced6b01f27d80gautam        return NL_OK;
27789b86262c90552a05a6177944d0ced6b01f27d80gautam    }
27889b86262c90552a05a6177944d0ced6b01f27d80gautam};
27989b86262c90552a05a6177944d0ced6b01f27d80gautam
28089b86262c90552a05a6177944d0ced6b01f27d80gautam
28189b86262c90552a05a6177944d0ced6b01f27d80gautamclass CancelResponderCommand : public WifiCommand
28289b86262c90552a05a6177944d0ced6b01f27d80gautam{
28389b86262c90552a05a6177944d0ced6b01f27d80gautam
28489b86262c90552a05a6177944d0ced6b01f27d80gautampublic:
28589b86262c90552a05a6177944d0ced6b01f27d80gautam    CancelResponderCommand(wifi_interface_handle iface, int id)
28689b86262c90552a05a6177944d0ced6b01f27d80gautam        : WifiCommand("CancelResponderCommand", iface, 0)/*, mChannelInfo(channel)*/
28789b86262c90552a05a6177944d0ced6b01f27d80gautam    {
28889b86262c90552a05a6177944d0ced6b01f27d80gautam
28989b86262c90552a05a6177944d0ced6b01f27d80gautam    }
29089b86262c90552a05a6177944d0ced6b01f27d80gautam
29189b86262c90552a05a6177944d0ced6b01f27d80gautam    virtual int create() {
29289b86262c90552a05a6177944d0ced6b01f27d80gautam        ALOGD("Creating message to cancel responder ; iface = %d", mIfaceInfo->id);
29389b86262c90552a05a6177944d0ced6b01f27d80gautam
29489b86262c90552a05a6177944d0ced6b01f27d80gautam        int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_RESPONDER);
29589b86262c90552a05a6177944d0ced6b01f27d80gautam        if (ret < 0) {
29689b86262c90552a05a6177944d0ced6b01f27d80gautam            return ret;
29789b86262c90552a05a6177944d0ced6b01f27d80gautam        }
29889b86262c90552a05a6177944d0ced6b01f27d80gautam
29989b86262c90552a05a6177944d0ced6b01f27d80gautam        return ret;
30089b86262c90552a05a6177944d0ced6b01f27d80gautam    }
30189b86262c90552a05a6177944d0ced6b01f27d80gautam
30289b86262c90552a05a6177944d0ced6b01f27d80gautamprotected:
30389b86262c90552a05a6177944d0ced6b01f27d80gautam    virtual int handleResponse(WifiEvent& reply) {
30489b86262c90552a05a6177944d0ced6b01f27d80gautam        /* Nothing to do on response! */
30589b86262c90552a05a6177944d0ced6b01f27d80gautam        return NL_SKIP;
30689b86262c90552a05a6177944d0ced6b01f27d80gautam    }
30789b86262c90552a05a6177944d0ced6b01f27d80gautam
30889b86262c90552a05a6177944d0ced6b01f27d80gautam};
30989b86262c90552a05a6177944d0ced6b01f27d80gautam
31089b86262c90552a05a6177944d0ced6b01f27d80gautam
311115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinclass RttCommand : public WifiCommand
312115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin{
313115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    unsigned numRttParams;
314215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    int mCompleted;
315215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    int currentIdx;
316215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    int totalCnt;
317215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    static const int MAX_RESULTS = 1024;
318215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    wifi_rtt_result *rttResults[MAX_RESULTS];
319115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    wifi_rtt_config *rttParams;
320115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    wifi_rtt_event_handler rttHandler;
321115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinpublic:
322115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
323215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
324d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande        : WifiCommand("RttCommand", iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
325215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        rttHandler(handler)
326215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    {
327215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        memset(rttResults, 0, sizeof(rttResults));
328215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        currentIdx = 0;
329215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        mCompleted = 0;
330215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        totalCnt = 0;
331215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com    }
332115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
333abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com    RttCommand(wifi_interface_handle iface, int id)
334d4f6adc737f93d75d3a1be8427a144f907a4dde6Vinit Deshpande        : WifiCommand("RttCommand", iface, id)
335abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com    {
336abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com        currentIdx = 0;
337abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com        mCompleted = 0;
338abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com        totalCnt = 0;
339abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com        numRttParams = 0;
340abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com    }
341115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
342115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    int createSetupRequest(WifiRequest& request) {
343115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        int result = request.create(GOOGLE_OUI, RTT_SUBCMD_SET_CONFIG);
344115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result < 0) {
345115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            return result;
346115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
347115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
348115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
349115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, numRttParams);
350115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result < 0) {
351115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            return result;
352115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
353115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO);
354115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        for (unsigned i = 0; i < numRttParams; i++) {
355115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            nlattr *attr2 = request.attr_start(i);
356115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (attr2 == NULL) {
357115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return WIFI_ERROR_OUT_OF_MEMORY;
358115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
359115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
360115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr);
361115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
362115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
363115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
364215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
365115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
366115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
367115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
368115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
369215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
370115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
371115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
372115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
373115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
374215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
375115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel,
376215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    sizeof(wifi_channel_info));
377115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
378115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
379115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
380215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
381215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
382115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
383115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
384115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
385215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
386215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
387215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    rttParams[i].num_frames_per_burst);
388115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
389115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
390115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
391215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
392215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
393c86b0f1aa52bb3e73a4ab2050a098f2ddc3d2a11xinhe                    rttParams[i].num_retries_per_rtt_frame);
394115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
395115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
396115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
397215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
398215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
399215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    rttParams[i].num_retries_per_ftmr);
400115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
401115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
402115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
403215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
404abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com            result = request.put_u32(RTT_ATTRIBUTE_TARGET_PERIOD,
405abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com                    rttParams[i].burst_period);
406abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com            if (result < 0) {
407abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com                return result;
408abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com            }
409abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com
410abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com            result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_DURATION,
411c86b0f1aa52bb3e73a4ab2050a098f2ddc3d2a11xinhe                    rttParams[i].burst_duration);
412215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            if (result < 0) {
413215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                return result;
414215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            }
415215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
416215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
417215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    rttParams[i].LCI_request);
418215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            if (result < 0) {
419215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                return result;
420215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            }
421215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
422215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
423215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    rttParams[i].LCR_request);
424215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            if (result < 0) {
425215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                return result;
426215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            }
427215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
428215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
429215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    rttParams[i].bw);
430215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            if (result < 0) {
431215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                return result;
432215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            }
433215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com
434215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
435215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    rttParams[i].preamble);
436115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
437115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
438115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
439115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            request.attr_end(attr2);
440115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
441115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
442115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        request.attr_end(rtt_config);
443115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        request.attr_end(data);
444115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return WIFI_SUCCESS;
445115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
446115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
447115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    int createTeardownRequest(WifiRequest& request, unsigned num_devices, mac_addr addr[]) {
4483acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        int result = request.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_CONFIG);
449115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result < 0) {
450115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            return result;
451115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
452115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
453115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
4543acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
455115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        for(unsigned i = 0; i < num_devices; i++) {
456115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
457115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result < 0) {
458115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                return result;
459115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
460115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
461115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        request.attr_end(data);
462115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return result;
463115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
464115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    int start() {
46568d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande        ALOGD("Setting RTT configuration");
466115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        WifiRequest request(familyId(), ifaceId());
467115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        int result = createSetupRequest(request);
468115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result != WIFI_SUCCESS) {
469115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            ALOGE("failed to create setup request; result = %d", result);
470115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            return result;
471115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
472115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
473115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        result = requestResponse(request);
474115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result != WIFI_SUCCESS) {
47568d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande            ALOGE("failed to configure RTT setup; result = %d", result);
476115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            return result;
477115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
478115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
479115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
48068d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande        ALOGI("Successfully started RTT operation");
481115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return result;
482115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
483115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
484115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    virtual int cancel() {
48568d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande        ALOGD("Stopping RTT");
486115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
487115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        WifiRequest request(familyId(), ifaceId());
488115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        int result = createTeardownRequest(request, 0, NULL);
489115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result != WIFI_SUCCESS) {
490115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            ALOGE("failed to create stop request; result = %d", result);
491115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        } else {
492115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = requestResponse(request);
493115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result != WIFI_SUCCESS) {
494115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin                ALOGE("failed to stop scan; result = %d", result);
495115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
496115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
497115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
49868d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande        unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
499115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return WIFI_SUCCESS;
500115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
501115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
502115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    int cancel_specific(unsigned num_devices, mac_addr addr[]) {
503abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com        ALOGE("Stopping RTT");
504115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
505115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        WifiRequest request(familyId(), ifaceId());
506115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        int result = createTeardownRequest(request, num_devices, addr);
507115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (result != WIFI_SUCCESS) {
508115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            ALOGE("failed to create stop request; result = %d", result);
509115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        } else {
510115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            result = requestResponse(request);
511115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            if (result != WIFI_SUCCESS) {
51268d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande                ALOGE("failed to stop RTT; result = %d", result);
513115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            }
514115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
515115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
51668d1fb64d52132a52bcad3450d6783939d8d9726Vinit Deshpande        unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
517115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return WIFI_SUCCESS;
518115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
519115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
520115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    virtual int handleResponse(WifiEvent& reply) {
521115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        /* Nothing to do on response! */
522115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return NL_SKIP;
523115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
524115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
525115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    virtual int handleEvent(WifiEvent& event) {
526732e4dd91aebbfb225feaed05893e2ec76842a10Vinit Deshpande        ALOGI("Got an RTT event");
527115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
528115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        int len = event.get_vendor_data_len();
529115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        if (vendor_data == NULL || len == 0) {
530115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin            ALOGI("No rtt results found");
531115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        }
532215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
533215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
534215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                mCompleted = it.get_u32();
535215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                ALOGI("retrieved completed flag : %d\n", mCompleted);
536215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            } else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
537215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                int result_cnt = 0;
538215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                mac_addr bssid;
539215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
540215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
541215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        memcpy(bssid, it2.get_data(), sizeof(mac_addr));
542215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        ALOGI("retrived target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
543215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                bssid[0],
544215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                bssid[1],
545215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                bssid[2],
546215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                bssid[3],
547215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                bssid[4],
548215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                bssid[5]);
549215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
550215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        result_cnt = it2.get_u32();
551215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        ALOGI("retrieved result_cnt : %d\n", result_cnt);
552215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
553215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        int result_len = it2.get_len();
554215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        rttResults[currentIdx] =  (wifi_rtt_result *)malloc(it2.get_len());
555215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        wifi_rtt_result *rtt_result = rttResults[currentIdx];
556215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        if (rtt_result == NULL) {
557215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            mCompleted = 1;
558215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            ALOGE("failed to allocate the wifi_rtt_result\n");
559215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            break;
560215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        }
561215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        memcpy(rtt_result, it2.get_data(), it2.get_len());
562215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        result_len -= sizeof(wifi_rtt_result);
563215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        if (result_len > 0) {
564215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            result_len -= sizeof(wifi_rtt_result);
565215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            dot11_rm_ie_t *ele_1;
566215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            dot11_rm_ie_t *ele_2;
567215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            /* The result has LCI or LCR element */
568215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            ele_1 = (dot11_rm_ie_t *)(rtt_result + 1);
569215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            if (ele_1->id == DOT11_MNG_MEASURE_REQUEST_ID) {
570215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                if (ele_1->type == DOT11_MEASURE_TYPE_LCI) {
571215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    rtt_result->LCI = (wifi_information_element *)ele_1;
572215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    result_len -= (ele_1->len + DOT11_HDR_LEN);
573215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    /* get a next rm ie */
574215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    if (result_len > 0) {
575215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                        ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
576215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                        if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
577215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                                (ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) {
578215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                            rtt_result->LCR = (wifi_information_element *)ele_2;
579215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                        }
580215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    }
581215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){
582215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    rtt_result->LCR = (wifi_information_element *)ele_1;
583215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    result_len -= (ele_1->len + DOT11_HDR_LEN);
584215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    /* get a next rm ie */
585215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    if (result_len > 0) {
586215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                        ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
587215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                        if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
588215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                                (ele_2->type == DOT11_MEASURE_TYPE_LCI)) {
589215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                            rtt_result->LCI = (wifi_information_element *)ele_2;
590215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                        }
591215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                    }
592215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                }
593215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                            }
594215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        }
595215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        totalCnt++;
596215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        ALOGI("retrived rtt_result : \n\tburst_num :%d, measurement_number : %d, success_number : %d\n"
597215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                "\tnumber_per_burst_peer : %d, status : %s, retry_after_duration : %d s\n"
598215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
599abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com                                "\tdistance : %d, burst_duration : %d ms, negotiated_burst_num : %d\n",
600215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                rtt_result->burst_num, rtt_result->measurement_number,
601215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                rtt_result->success_number, rtt_result->number_per_burst_peer,
602215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                get_err_info(rtt_result->status), rtt_result->retry_after_duration,
603215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                                rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
60443f0887a640ec4c9e56dfe6f68621039e1ba3e58Etan Cohen                                rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
605abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com                                rtt_result->burst_duration, rtt_result->negotiated_burst_num);
606215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                        currentIdx++;
607215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                    }
608215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                }
609215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            }
610115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
611215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        }
612215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        if (mCompleted) {
613215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
614215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            (*rttHandler.on_rtt_results)(id(), totalCnt, rttResults);
615215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            for (int i = 0; i < currentIdx; i++) {
616215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                free(rttResults[i]);
617215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com                rttResults[i] = NULL;
618215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            }
619215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com            totalCnt = currentIdx = 0;
6206fcd7d0c4754b6bcf691f8be6a3618b23a4e0b55eccopark@broadcom.com            WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
6216fcd7d0c4754b6bcf691f8be6a3618b23a4e0b55eccopark@broadcom.com            if (cmd)
6226fcd7d0c4754b6bcf691f8be6a3618b23a4e0b55eccopark@broadcom.com                cmd->releaseRef();
623215b92f52a64b5f4b56589fcb7c788fc68b43aa5eccopark@broadcom.com        }
624115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        return NL_SKIP;
625115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    }
626115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin};
627115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
628115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
629115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin/* API to request RTT measurement */
630115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinwifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
631115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
632115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin{
633115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    wifi_handle handle = getWifiHandle(iface);
634115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
6356af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
6366af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    wifi_error result = wifi_register_cmd(handle, id, cmd);
6376af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    if (result != WIFI_SUCCESS) {
6386af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma        cmd->releaseRef();
6396af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma        return result;
6406af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    }
6416af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    result = (wifi_error)cmd->start();
6426af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    if (result != WIFI_SUCCESS) {
6436af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma        wifi_unregister_cmd(handle, id);
6446af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma        cmd->releaseRef();
6456af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma        return result;
6466af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    }
6476af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    return result;
648115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin}
649115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin
650115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin/* API to cancel RTT measurements */
651115bcffc16c53e9552c09a6792666c52a633b4f2Ashwinwifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle iface,
652115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin        unsigned num_devices, mac_addr addr[])
653115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin{
654115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin    wifi_handle handle = getWifiHandle(iface);
655abe2d4864c8f15e4eb6d7dab64b159e47a605c21eccopark@broadcom.com    RttCommand *cmd = new RttCommand(iface, id);
6566af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
6576af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    cmd->cancel_specific(num_devices, addr);
6586af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    cmd->releaseRef();
6596af064b77bfdc84a6f425a7c9d0941fad11f4489Sreenath Sharma    return WIFI_SUCCESS;
660115bcffc16c53e9552c09a6792666c52a633b4f2Ashwin}
66128237f92de2634ec1d529c63b2d61d80e7485c83Vinit Deshpande
6623acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park/* API to get RTT capability */
6633acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco parkwifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
6643acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park        wifi_rtt_capabilities *capabilities)
6653acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park{
6663acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    GetRttCapabilitiesCommand command(iface, capabilities);
6673acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park    return (wifi_error) command.requestResponse();
6683acd5f599fa32a9a66a1f5bda8f17b4837140924Ecco park}
66989b86262c90552a05a6177944d0ced6b01f27d80gautam
670d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam/* API to get the responder information */
671d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautamwifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
672d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam        wifi_rtt_responder* responderInfo)
67389b86262c90552a05a6177944d0ced6b01f27d80gautam{
674d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam    GetRttResponderInfoCommand command(iface, responderInfo);
67589b86262c90552a05a6177944d0ced6b01f27d80gautam    return (wifi_error) command.requestResponse();
67689b86262c90552a05a6177944d0ced6b01f27d80gautam
67789b86262c90552a05a6177944d0ced6b01f27d80gautam}
67889b86262c90552a05a6177944d0ced6b01f27d80gautam
67989b86262c90552a05a6177944d0ced6b01f27d80gautam/**
68089b86262c90552a05a6177944d0ced6b01f27d80gautam * Enable RTT responder mode.
68189b86262c90552a05a6177944d0ced6b01f27d80gautam * channel_hint - hint of the channel information where RTT responder should be enabled on.
68289b86262c90552a05a6177944d0ced6b01f27d80gautam * max_duration_seconds - timeout of responder mode.
683d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam * wifi_rtt_responder - information for RTT responder e.g. channel used and preamble supported.
68489b86262c90552a05a6177944d0ced6b01f27d80gautam */
68589b86262c90552a05a6177944d0ced6b01f27d80gautamwifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
68689b86262c90552a05a6177944d0ced6b01f27d80gautam                                wifi_channel_info channel_hint, unsigned max_duration_seconds,
687d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam                                wifi_rtt_responder* responderInfo)
68889b86262c90552a05a6177944d0ced6b01f27d80gautam{
689d122c5c4cbdb8fdee2576789733e42ea0ecb9d9cgautam    EnableResponderCommand command(iface, id, channel_hint, max_duration_seconds, responderInfo);
69089b86262c90552a05a6177944d0ced6b01f27d80gautam    return (wifi_error) command.requestResponse();
69189b86262c90552a05a6177944d0ced6b01f27d80gautam}
69289b86262c90552a05a6177944d0ced6b01f27d80gautam
69389b86262c90552a05a6177944d0ced6b01f27d80gautam/**
69489b86262c90552a05a6177944d0ced6b01f27d80gautam * Disable RTT responder mode.
69589b86262c90552a05a6177944d0ced6b01f27d80gautam */
69689b86262c90552a05a6177944d0ced6b01f27d80gautamwifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface)
69789b86262c90552a05a6177944d0ced6b01f27d80gautam{
69889b86262c90552a05a6177944d0ced6b01f27d80gautam    CancelResponderCommand command(iface, id);
69989b86262c90552a05a6177944d0ced6b01f27d80gautam    return (wifi_error) command.requestResponse();
70089b86262c90552a05a6177944d0ced6b01f27d80gautam}
70189b86262c90552a05a6177944d0ced6b01f27d80gautam
702