• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Portions copyright (C) 2023 Broadcom Limited
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <sys/socket.h>
22 #include <netlink/genl/genl.h>
23 #include <netlink/genl/family.h>
24 #include <netlink/genl/ctrl.h>
25 #include <linux/rtnetlink.h>
26 #include <netpacket/packet.h>
27 #include <linux/filter.h>
28 #include <linux/errqueue.h>
29 
30 #include <linux/pkt_sched.h>
31 #include <netlink/object-api.h>
32 #include <netlink/netlink.h>
33 #include <netlink/socket.h>
34 
35 #include "nl80211_copy.h"
36 
37 #include "sync.h"
38 
39 #define LOG_TAG  "WifiHAL"
40 
41 #include <log/log.h>
42 #include <utils/String8.h>
43 
44 #include <hardware_legacy/wifi_hal.h>
45 #include "common.h"
46 #include "cpp_bindings.h"
47 
48 using namespace android;
49 #define RTT_RESULT_V3_SIZE (sizeof(wifi_rtt_result_v3))
50 #define RTT_RESULT_V2_SIZE (sizeof(wifi_rtt_result_v2))
51 #define RTT_RESULT_V1_SIZE (sizeof(wifi_rtt_result))
52 #define UNSPECIFIED -1 // wifi HAL common definition for unspecified value
53 typedef enum {
54 
55     RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
56     RTT_SUBCMD_CANCEL_CONFIG,
57     RTT_SUBCMD_GETCAPABILITY,
58     RTT_SUBCMD_GETAVAILCHANNEL,
59     RTT_SUBCMD_SET_RESPONDER,
60     RTT_SUBCMD_CANCEL_RESPONDER,
61 } RTT_SUB_COMMAND;
62 
63 typedef enum {
64     RTT_ATTRIBUTE_TARGET_INVALID            = 0,
65     RTT_ATTRIBUTE_TARGET_CNT                = 1,
66     RTT_ATTRIBUTE_TARGET_INFO               = 2,
67     RTT_ATTRIBUTE_TARGET_MAC                = 3,
68     RTT_ATTRIBUTE_TARGET_TYPE               = 4,
69     RTT_ATTRIBUTE_TARGET_PEER               = 5,
70     RTT_ATTRIBUTE_TARGET_CHAN               = 6,
71     RTT_ATTRIBUTE_TARGET_PERIOD             = 7,
72     RTT_ATTRIBUTE_TARGET_NUM_BURST          = 8,
73     RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST      = 9,
74     RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM      = 10,
75     RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR     = 11,
76     RTT_ATTRIBUTE_TARGET_LCI                = 12,
77     RTT_ATTRIBUTE_TARGET_LCR                = 13,
78     RTT_ATTRIBUTE_TARGET_BURST_DURATION     = 14,
79     RTT_ATTRIBUTE_TARGET_PREAMBLE           = 15,
80     RTT_ATTRIBUTE_TARGET_BW                 = 16,
81     RTT_ATTRIBUTE_TARGET_NTB_MIN_MEAS_TIME  = 17,
82     RTT_ATTRIBUTE_TARGET_NTB_MAX_MEAS_TIME  = 18,
83     /* Add Attributes related to the event */
84     RTT_ATTRIBUTE_RESULTS_COMPLETE          = 30,
85     RTT_ATTRIBUTE_RESULTS_PER_TARGET        = 31,
86     RTT_ATTRIBUTE_RESULT_CNT                = 32,
87     RTT_ATTRIBUTE_RESULT                    = 33,
88     RTT_ATTRIBUTE_RESUTL_DETAIL             = 34,
89     RTT_ATTRIBUTE_RESULT_FREQ               = 35,
90     RTT_ATTRIBUTE_RESULT_BW                 = 36,
91     RTT_ATTRIBUTE_RESULT_I2R_TX_LTF_RPT_CNT = 37,
92     RTT_ATTRIBUTE_RESULT_R2I_TX_LTF_RPT_CNT = 38,
93     RTT_ATTRIBUTE_RESULT_NTB_MIN_MEAS_TIME  = 39,
94     RTT_ATTRIBUTE_RESULT_NTB_MAX_MEAS_TIME  = 40,
95     /* Add any new RTT_ATTRIBUTE prior to RTT_ATTRIBUTE_MAX */
96     RTT_ATTRIBUTE_MAX
97 } RTT_ATTRIBUTE;
98 typedef struct strmap_entry {
99     int			id;
100     String8		text;
101 } strmap_entry_t;
102 struct dot11_rm_ie {
103     u8 id;
104     u8 len;
105     u8 token;
106     u8 mode;
107     u8 type;
108 } __attribute__ ((packed));
109 typedef struct dot11_rm_ie dot11_rm_ie_t;
110 #define DOT11_HDR_LEN 2
111 #define DOT11_RM_IE_LEN       5
112 #define DOT11_MNG_MEASURE_REQUEST_ID		38	/* 11H MeasurementRequest */
113 #define DOT11_MNG_MEASURE_REPORT_ID		39	/* 11H MeasurementResponse */
114 #define DOT11_MEASURE_TYPE_LCI		8   /* d11 measurement LCI type */
115 #define DOT11_MEASURE_TYPE_CIVICLOC	11  /* d11 measurement location civic */
116 
117 static const strmap_entry_t err_info[] = {
118     {RTT_STATUS_SUCCESS, String8("Success")},
119     {RTT_STATUS_FAILURE, String8("Failure")},
120     {RTT_STATUS_FAIL_NO_RSP, String8("No reponse")},
121     {RTT_STATUS_FAIL_INVALID_TS, String8("Invalid Timestamp")},
122     {RTT_STATUS_FAIL_PROTOCOL, String8("Protocol error")},
123     {RTT_STATUS_FAIL_REJECTED, String8("Rejected")},
124     {RTT_STATUS_FAIL_NOT_SCHEDULED_YET, String8("not scheduled")},
125     {RTT_STATUS_FAIL_SCHEDULE,  String8("schedule failed")},
126     {RTT_STATUS_FAIL_TM_TIMEOUT, String8("timeout")},
127     {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, String8("AP is on difference channel")},
128     {RTT_STATUS_FAIL_NO_CAPABILITY, String8("no capability")},
129     {RTT_STATUS_FAIL_BUSY_TRY_LATER, String8("busy and try later")},
130     {RTT_STATUS_ABORTED, String8("aborted")}
131 };
132 
133     static const char*
get_err_info(int status)134 get_err_info(int status)
135 {
136     int i;
137     const strmap_entry_t *p_entry;
138     int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
139     /* scan thru the table till end */
140     p_entry = err_info;
141     for (i = 0; i < (int) num_entries; i++)
142     {
143         if (p_entry->id == status)
144             return p_entry->text.c_str();
145         p_entry++;		/* next entry */
146     }
147     return "unknown error";			/* not found */
148 }
149 
150 class GetRttCapabilitiesCommand : public WifiCommand
151 {
152     wifi_rtt_capabilities_v3 *mCapabilities;
153 public:
GetRttCapabilitiesCommand(wifi_interface_handle iface,wifi_rtt_capabilities_v3 * capabitlites)154     GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities_v3 *capabitlites)
155         : WifiCommand("GetRttCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
156     {
157         memset(mCapabilities, 0, sizeof(*mCapabilities));
158     }
159 
create()160     virtual int create() {
161         ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
162 
163         int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETCAPABILITY);
164         if (ret < 0) {
165             return ret;
166         }
167 
168         return ret;
169     }
170 
171 protected:
handleResponse(WifiEvent & reply)172     virtual int handleResponse(WifiEvent& reply) {
173 
174         ALOGD("In GetRttCapabilitiesCommand::handleResponse");
175 
176         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
177             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
178             return NL_SKIP;
179         }
180 
181         int id = reply.get_vendor_id();
182         int subcmd = reply.get_vendor_subcmd();
183 
184         void *data = reply.get_vendor_data();
185         int len = reply.get_vendor_data_len();
186 
187         ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
188                 sizeof(*mCapabilities));
189 
190         memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
191 
192         return NL_OK;
193     }
194 };
195 
196 
197 class GetRttResponderInfoCommand : public WifiCommand
198 {
199     wifi_rtt_responder* mResponderInfo;
200 public:
GetRttResponderInfoCommand(wifi_interface_handle iface,wifi_rtt_responder * responderInfo)201     GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
202         : WifiCommand("GetRttResponderInfoCommand", iface, 0), mResponderInfo(responderInfo)
203     {
204         memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
205 
206     }
207 
create()208     virtual int create() {
209         ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
210 
211         int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETAVAILCHANNEL);
212         if (ret < 0) {
213             return ret;
214         }
215 
216         return ret;
217     }
218 
219 protected:
handleResponse(WifiEvent & reply)220     virtual int handleResponse(WifiEvent& reply) {
221 
222         ALOGD("In GetRttResponderInfoCommand::handleResponse");
223 
224         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
225             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
226             return NL_SKIP;
227         }
228 
229         int id = reply.get_vendor_id();
230         int subcmd = reply.get_vendor_subcmd();
231 
232         void *data = reply.get_vendor_data();
233         int len = reply.get_vendor_data_len();
234 
235         ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
236                 sizeof(*mResponderInfo));
237 
238         memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
239 
240         return NL_OK;
241     }
242 };
243 
244 
245 class EnableResponderCommand : public WifiCommand
246 {
247     wifi_channel_info  mChannelInfo;
248     wifi_rtt_responder* mResponderInfo;
249     unsigned int m_max_duration_sec;
250 public:
EnableResponderCommand(wifi_interface_handle iface,int id,wifi_channel_info channel_hint,unsigned max_duration_seconds,wifi_rtt_responder * responderInfo)251     EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
252             unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
253             : WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
254             mResponderInfo(responderInfo), m_max_duration_sec(max_duration_seconds)
255     {
256         memset(mResponderInfo, 0, sizeof(*mResponderInfo));
257         memset(&mChannelInfo, 0, sizeof(mChannelInfo));
258         m_max_duration_sec = 0;
259     }
260 
create()261     virtual int create() {
262         ALOGD("Creating message to set responder ; iface = %d", mIfaceInfo->id);
263 
264         int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_SET_RESPONDER);
265         if (ret < 0) {
266             return ret;
267         }
268 
269         return ret;
270     }
271 
272 protected:
handleResponse(WifiEvent & reply)273     virtual int handleResponse(WifiEvent& reply) {
274 
275         ALOGD("In EnableResponderCommand::handleResponse");
276 
277         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
278             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
279             return NL_SKIP;
280         }
281 
282         int id = reply.get_vendor_id();
283         int subcmd = reply.get_vendor_subcmd();
284 
285         void *data = reply.get_vendor_data();
286         int len = reply.get_vendor_data_len();
287 
288         ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
289                 sizeof(*mResponderInfo));
290 
291         memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
292 
293         return NL_OK;
294     }
295 };
296 
297 
298 class CancelResponderCommand : public WifiCommand
299 {
300 
301 public:
CancelResponderCommand(wifi_interface_handle iface,int id)302     CancelResponderCommand(wifi_interface_handle iface, int id)
303         : WifiCommand("CancelResponderCommand", iface, 0)/*, mChannelInfo(channel)*/
304     {
305 
306     }
307 
create()308     virtual int create() {
309         ALOGD("Creating message to cancel responder ; iface = %d", mIfaceInfo->id);
310 
311         int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_RESPONDER);
312         if (ret < 0) {
313             return ret;
314         }
315 
316         return ret;
317     }
318 
319 protected:
handleResponse(WifiEvent & reply)320     virtual int handleResponse(WifiEvent& reply) {
321         /* Nothing to do on response! */
322         return NL_SKIP;
323     }
324 
325 };
326 
327 
328 class RttCommand : public WifiCommand
329 {
330     unsigned numRttParams;
331     int mCompleted;
332     int currentIdx = 0;
333     int totalCnt = 0;
334     static const int MAX_RESULTS = 1024;
335     wifi_rtt_result *rttResultsV1[MAX_RESULTS];
336     wifi_rtt_result_v2 *rttResultsV2[MAX_RESULTS];
337     wifi_rtt_result_v3 *rttResultsV3[MAX_RESULTS];
338     wifi_rtt_config_v3 *rttParams;
339     wifi_rtt_event_handler_v3 rttHandler;
340     int nextidx = 0;
341     wifi_channel channel = 0;
342     wifi_rtt_bw bw;
343     int result_size = 0;
344     int opt_result_size = 0;
345     u8 i2r_tx_ltf_repetition_count = 0;
346     u8 r2i_tx_ltf_repetition_count = 0;
347     u32 ntb_min_measurement_time = 0;
348     u32 ntb_max_measurement_time = 0;
349 
350 public:
RttCommand(wifi_interface_handle iface,int id,unsigned num_rtt_config,wifi_rtt_config_v3 rtt_config[],wifi_rtt_event_handler_v3 handler)351     RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
352             wifi_rtt_config_v3 rtt_config[], wifi_rtt_event_handler_v3 handler)
353         : WifiCommand("RttCommand", iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
354         rttHandler(handler)
355     {
356         memset(rttResultsV1, 0, sizeof(rttResultsV1));
357         memset(rttResultsV2, 0, sizeof(rttResultsV2));
358         memset(rttResultsV3, 0, sizeof(rttResultsV3));
359         currentIdx = 0;
360         mCompleted = 0;
361         totalCnt = 0;
362         channel = 0;
363         result_size = 0;
364         opt_result_size = 0;
365         channel = 0;
366         result_size = 0;
367         opt_result_size = 0;
368     }
369 
RttCommand(wifi_interface_handle iface,int id)370     RttCommand(wifi_interface_handle iface, int id)
371         : WifiCommand("RttCommand", iface, id)
372     {
373         currentIdx = 0;
374         mCompleted = 0;
375         totalCnt = 0;
376         numRttParams = 0;
377         memset(rttResultsV1, 0, sizeof(rttResultsV1));
378         memset(rttResultsV2, 0, sizeof(rttResultsV2));
379         memset(rttResultsV3, 0, sizeof(rttResultsV3));
380         rttParams = NULL;
381         rttHandler.on_rtt_results_v3 = NULL;
382         channel = 0;
383         result_size = 0;
384         opt_result_size = 0;
385     }
386 
createSetupRequest(WifiRequest & request)387     int createSetupRequest(WifiRequest& request) {
388         int result = request.create(GOOGLE_OUI, RTT_SUBCMD_SET_CONFIG);
389         if (result < 0) {
390             return result;
391         }
392 
393         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
394         result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, numRttParams);
395         if (result < 0) {
396             return result;
397         }
398         nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO);
399         for (unsigned i = 0; i < numRttParams; i++) {
400             nlattr *attr2 = request.attr_start(i);
401             if (attr2 == NULL) {
402                 return WIFI_ERROR_OUT_OF_MEMORY;
403             }
404 
405             result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].rtt_config.addr);
406             if (result < 0) {
407                 return result;
408             }
409 
410             result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].rtt_config.type);
411             if (result < 0) {
412                 return result;
413             }
414 
415             result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].rtt_config.peer);
416             if (result < 0) {
417                 return result;
418             }
419 
420             result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].rtt_config.channel,
421                     sizeof(wifi_channel_info));
422             if (result < 0) {
423                 return result;
424             }
425 
426             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST,
427                     rttParams[i].rtt_config.num_burst);
428             if (result < 0) {
429                 return result;
430             }
431 
432             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
433                     rttParams[i].rtt_config.num_frames_per_burst);
434             if (result < 0) {
435                 return result;
436             }
437 
438             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
439                     rttParams[i].rtt_config.num_retries_per_rtt_frame);
440             if (result < 0) {
441                 return result;
442             }
443 
444             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
445                     rttParams[i].rtt_config.num_retries_per_ftmr);
446             if (result < 0) {
447                 return result;
448             }
449 
450             result = request.put_u32(RTT_ATTRIBUTE_TARGET_PERIOD,
451                     rttParams[i].rtt_config.burst_period);
452             if (result < 0) {
453                 return result;
454             }
455 
456             result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_DURATION,
457                     rttParams[i].rtt_config.burst_duration);
458             if (result < 0) {
459                 return result;
460             }
461 
462             result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
463                     rttParams[i].rtt_config.LCI_request);
464             if (result < 0) {
465                 return result;
466             }
467 
468             result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
469                     rttParams[i].rtt_config.LCR_request);
470             if (result < 0) {
471                 return result;
472             }
473 
474             result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
475                     rttParams[i].rtt_config.bw);
476             if (result < 0) {
477                 return result;
478             }
479 
480             result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
481                     rttParams[i].rtt_config.preamble);
482             if (result < 0) {
483                 return result;
484             }
485 
486             /* Below params are applicable for only 11az ranging */
487             if (rttParams[i].rtt_config.type == RTT_TYPE_2_SIDED_11AZ_NTB) {
488                 result = request.put_u32(RTT_ATTRIBUTE_TARGET_NTB_MIN_MEAS_TIME,
489                         rttParams[i].ntb_min_measurement_time);
490                 if (result < 0) {
491                     return result;
492                 }
493 
494                 result = request.put_u32(RTT_ATTRIBUTE_TARGET_NTB_MAX_MEAS_TIME,
495                         rttParams[i].ntb_max_measurement_time);
496                 if (result < 0) {
497                     return result;
498                 }
499             }
500 
501             request.attr_end(attr2);
502         }
503 
504         request.attr_end(rtt_config);
505         request.attr_end(data);
506         return WIFI_SUCCESS;
507     }
508 
createTeardownRequest(WifiRequest & request,unsigned num_devices,mac_addr addr[])509     int createTeardownRequest(WifiRequest& request, unsigned num_devices, mac_addr addr[]) {
510         int result = request.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_CONFIG);
511         if (result < 0) {
512             return result;
513         }
514 
515         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
516         result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
517 
518         if (result < 0) {
519             return result;
520         }
521         for(unsigned i = 0; i < num_devices; i++) {
522             result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
523             if (result < 0) {
524                 return result;
525             }
526         }
527         request.attr_end(data);
528         return result;
529     }
530 
start()531     int start() {
532         ALOGD("Setting RTT configuration");
533         WifiRequest request(familyId(), ifaceId());
534         int result = createSetupRequest(request);
535         if (result != WIFI_SUCCESS) {
536             ALOGE("failed to create setup request; result = %d", result);
537             return result;
538         }
539 
540         registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
541 
542         result = requestResponse(request);
543         if (result != WIFI_SUCCESS) {
544             unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
545             ALOGE("failed to configure RTT setup; result = %d", result);
546             return result;
547         }
548 
549         ALOGI("Successfully started RTT operation");
550         return result;
551     }
552 
cancel()553     virtual int cancel() {
554         ALOGD("Stopping RTT");
555 
556         WifiRequest request(familyId(), ifaceId());
557         int result = createTeardownRequest(request, 0, NULL);
558         if (result != WIFI_SUCCESS) {
559             ALOGE("failed to create stop request; result = %d", result);
560         } else {
561             result = requestResponse(request);
562             if (result != WIFI_SUCCESS) {
563                 ALOGE("failed to stop scan; result = %d", result);
564             }
565         }
566 
567         unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
568         ALOGD("Stopped RTT");
569         return WIFI_SUCCESS;
570     }
571 
cancel_specific(unsigned num_devices,mac_addr addr[])572     int cancel_specific(unsigned num_devices, mac_addr addr[]) {
573         ALOGE("Stopping RTT");
574 
575         WifiRequest request(familyId(), ifaceId());
576         int result = createTeardownRequest(request, num_devices, addr);
577         if (result != WIFI_SUCCESS) {
578             ALOGE("failed to create stop request; result = %d", result);
579         } else {
580             result = requestResponse(request);
581             if (result != WIFI_SUCCESS) {
582                 ALOGE("failed to stop RTT; result = %d", result);
583             }
584         }
585 
586         unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
587         return WIFI_SUCCESS;
588     }
589 
handleResponse(WifiEvent & reply)590     virtual int handleResponse(WifiEvent& reply) {
591         /* Nothing to do on response! */
592         return NL_SKIP;
593     }
594 
handleEvent(WifiEvent & event)595     virtual int handleEvent(WifiEvent& event) {
596         ALOGI("Got an RTT event");
597         nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
598         int len = event.get_vendor_data_len();
599         if (vendor_data == NULL || len == 0) {
600             ALOGI("No rtt results found");
601             return NL_STOP;
602         }
603 
604         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
605             if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
606                 mCompleted = it.get_u32();
607                 ALOGI("Completed flag : %d\n", mCompleted);
608             } else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
609                 int result_cnt = 0;
610                 mac_addr bssid;
611                 for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
612                     if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
613                         memcpy(bssid, it2.get_data(), sizeof(mac_addr));
614                         ALOGI("target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
615                                 bssid[0], bssid[1], bssid[2], bssid[3],
616                                 bssid[4], bssid[5]);
617                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_FREQ) {
618                         channel = it2.get_u32();
619                         if (rttResultsV3[currentIdx] == NULL) {
620                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
621                             break;
622                         }
623                         if (!channel) {
624                             rttResultsV3[currentIdx]->rtt_result.frequency =
625                                     UNSPECIFIED;
626                         } else {
627                             rttResultsV3[currentIdx]->rtt_result.frequency =
628                                     channel;
629                         }
630 
631                         ALOGI("rtt_resultV3 : \n\tchannel :%d",
632                                 rttResultsV3[currentIdx]->rtt_result.frequency);
633                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_BW) {
634                         bw = (wifi_rtt_bw)it2.get_u32();
635                         if (rttResultsV3[currentIdx] == NULL) {
636                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
637                             break;
638                         }
639                         rttResultsV3[currentIdx]->rtt_result.packet_bw =
640                                 bw;
641 
642                         ALOGI("rtt_resultV3 : \n\tpacket_bw :%d",
643                                rttResultsV3[currentIdx]->rtt_result.packet_bw);
644                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
645                         result_cnt = it2.get_u32();
646                         ALOGI("result_cnt : %d\n", result_cnt);
647                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_I2R_TX_LTF_RPT_CNT) {
648                         i2r_tx_ltf_repetition_count = it2.get_u8();
649                         if (rttResultsV3[currentIdx] == NULL) {
650                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
651                             break;
652                         }
653                         rttResultsV3[currentIdx]->i2r_tx_ltf_repetition_count =
654                                 i2r_tx_ltf_repetition_count;
655                         ALOGI("rtt_resultv3 : \n\ti2r_tx_ltf_repetition_count :%d",
656                                 rttResultsV3[currentIdx]->i2r_tx_ltf_repetition_count);
657                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_R2I_TX_LTF_RPT_CNT) {
658                         r2i_tx_ltf_repetition_count = it2.get_u8();
659                         if (rttResultsV3[currentIdx] == NULL) {
660                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
661                             break;
662                         }
663                         rttResultsV3[currentIdx]->r2i_tx_ltf_repetition_count =
664                                 r2i_tx_ltf_repetition_count;
665                         ALOGI("rtt_resultv3 : \n\tr2i_tx_ltf_repetition_count :%d",
666                                 rttResultsV3[currentIdx]->r2i_tx_ltf_repetition_count);
667                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_NTB_MIN_MEAS_TIME) {
668                         ntb_min_measurement_time = it2.get_u32();
669                         if (rttResultsV3[currentIdx] == NULL) {
670                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
671                             break;
672                         }
673                         rttResultsV3[currentIdx]->ntb_min_measurement_time =
674                                 ntb_min_measurement_time;
675                         ALOGI("rtt_resultv3 : \n\t ntb_min_measurement_time :%lu units of 100 us",
676                                 rttResultsV3[currentIdx]->ntb_min_measurement_time);
677                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_NTB_MAX_MEAS_TIME) {
678                         ntb_max_measurement_time = it2.get_u32();
679                         if (rttResultsV3[currentIdx] == NULL) {
680                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
681                             break;
682                         }
683                         rttResultsV3[currentIdx]->ntb_max_measurement_time =
684                                 ntb_max_measurement_time;
685                         ALOGI("rtt_resultv3 : \n\t ntb_max_measurement_time:%lu units of 10ms",
686                                 rttResultsV3[currentIdx]->ntb_max_measurement_time);
687                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
688                         currentIdx = nextidx;
689                         int result_len = it2.get_len();
690                         rttResultsV1[currentIdx] =
691                                 (wifi_rtt_result *)malloc(it2.get_len());
692                         wifi_rtt_result *rtt_results_v1 = rttResultsV1[currentIdx];
693                         if (rtt_results_v1 == NULL) {
694                             mCompleted = 1;
695                             ALOGE("failed to allocate the wifi_result_v1\n");
696                             break;
697                         }
698 
699                         /* Populate to the rtt_results_v1 struct */
700                         memcpy(rtt_results_v1, it2.get_data(), it2.get_len());
701 
702                         /* handle the optional data */
703                         result_len -= RTT_RESULT_V1_SIZE;
704                         if (result_len > 0) {
705                             dot11_rm_ie_t *ele_1;
706                             dot11_rm_ie_t *ele_2;
707                             /* The result has LCI or LCR element */
708                             ele_1 = (dot11_rm_ie_t *)(rtt_results_v1 + 1);
709                             if (ele_1->id == DOT11_MNG_MEASURE_REPORT_ID) {
710                                 if (ele_1->type == DOT11_MEASURE_TYPE_LCI) {
711                                     rtt_results_v1->LCI = (wifi_information_element *)ele_1;
712                                     result_len -= (ele_1->len + DOT11_HDR_LEN);
713                                     opt_result_size += (ele_1->len + DOT11_HDR_LEN);
714                                     /* get a next rm ie */
715                                     if (result_len > 0) {
716                                         ele_2 = (dot11_rm_ie_t *)((char *)ele_1 +
717                                             (ele_1->len + DOT11_HDR_LEN));
718                                         if ((ele_2->id == DOT11_MNG_MEASURE_REPORT_ID) &&
719                                                 (ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) {
720                                             rtt_results_v1->LCR = (wifi_information_element *)ele_2;
721                                         }
722                                     }
723                                 } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC) {
724                                     rtt_results_v1->LCR = (wifi_information_element *)ele_1;
725                                     result_len -= (ele_1->len + DOT11_HDR_LEN);
726                                     opt_result_size += (ele_1->len + DOT11_HDR_LEN);
727                                     /* get a next rm ie */
728                                     if (result_len > 0) {
729                                         ele_2 = (dot11_rm_ie_t *)((char *)ele_1 +
730                                                 (ele_1->len + DOT11_HDR_LEN));
731                                         if ((ele_2->id == DOT11_MNG_MEASURE_REPORT_ID) &&
732                                                 (ele_2->type == DOT11_MEASURE_TYPE_LCI)) {
733                                             rtt_results_v1->LCI = (wifi_information_element *)ele_2;
734                                         }
735                                     }
736                                 }
737                             }
738                         }
739 
740                         /* Alloc struct v2 including new elements of ver2 */
741                         rttResultsV2[currentIdx] =
742                                 (wifi_rtt_result_v2 *)malloc(RTT_RESULT_V2_SIZE + opt_result_size);
743                         wifi_rtt_result_v2 *rtt_result_v2 = rttResultsV2[currentIdx];
744                         if (rtt_result_v2 == NULL) {
745                             ALOGE("failed to allocate the rtt_result\n");
746                             break;
747                         }
748 
749                         /* Populate the v2 result struct as per the v1 result struct elements */
750                         memcpy(&rtt_result_v2->rtt_result,
751                                 (wifi_rtt_result *)rtt_results_v1, RTT_RESULT_V1_SIZE);
752                         if (!channel) {
753                             rtt_result_v2->frequency = UNSPECIFIED;
754                         }
755 
756                         /* Copy the optional v1 data to v2 struct */
757                         if (opt_result_size &&
758                             (opt_result_size == (it2.get_len() - RTT_RESULT_V1_SIZE))) {
759 
760                             wifi_rtt_result_v2 *opt_rtt_result_v2 = NULL;
761                             /* Intersect the optional data from v1 rtt result struct */
762                             wifi_rtt_result *opt_rtt_result_v1 =
763                                     (wifi_rtt_result *)(rtt_results_v1 + 1);
764 
765                             /* Move to v2 ptr to the start of the optional params */
766                             opt_rtt_result_v2 =
767                                     (wifi_rtt_result_v2 *)(rtt_result_v2 + 1);
768 
769                             /* Append optional rtt_result_v1 data to optional rtt_result_v2 */
770                             memcpy(opt_rtt_result_v2, opt_rtt_result_v1,
771                                     (it2.get_len() - RTT_RESULT_V1_SIZE));
772                         } else {
773                            ALOGI("Optional rtt result elements missing, skip processing\n");
774                         }
775 
776                         /* Alloc struct v3 including new elements, reserve for new elements */
777                         rttResultsV3[currentIdx] =
778                                 (wifi_rtt_result_v3 *)malloc(RTT_RESULT_V3_SIZE + opt_result_size);
779                         wifi_rtt_result_v3 *rtt_result_v3 = rttResultsV3[currentIdx];
780                         if (rtt_result_v3 == NULL) {
781                             ALOGE("failed to allocate the rtt_result ver3\n");
782                             break;
783                         }
784 
785                         /* Populate the v3 struct with v1 struct, v1 struct opt + v2 struct + v2 struct opt */
786                         memcpy(&rtt_result_v3->rtt_result,
787                                 (wifi_rtt_result_v2 *)rtt_result_v2,
788                                 RTT_RESULT_V2_SIZE + opt_result_size);
789 
790                         totalCnt++;
791                         nextidx = currentIdx;
792                         nextidx++;
793                     }
794                 }
795                 ALOGI("Current Id: %d: retrieved rtt_resultv3 :\n"
796                             " burst_num : %d, measurement_number : %d,\n"
797                             " success_number : %d, number_per_burst_peer : %d, status : %s,\n"
798                             " retry_after_duration : %d rssi : %d dbm,\n"
799                             " rx_rate : %d Kbps, rtt : %lu pss, rtt_sd : %lu ps,\n"
800                             " distance : %d mm, burst_duration : %d ms, freq : %d,\n"
801                             " packet_bw : %d, negotiated_burst_num : %d\n",
802                             currentIdx,
803                             rttResultsV3[currentIdx]->rtt_result.rtt_result.burst_num,
804                             rttResultsV3[currentIdx]->rtt_result.rtt_result.measurement_number,
805                             rttResultsV3[currentIdx]->rtt_result.rtt_result.success_number,
806                             rttResultsV3[currentIdx]->rtt_result.rtt_result.number_per_burst_peer,
807                             get_err_info(rttResultsV3[currentIdx]->rtt_result.rtt_result.status),
808                             rttResultsV3[currentIdx]->rtt_result.rtt_result.retry_after_duration,
809                             rttResultsV3[currentIdx]->rtt_result.rtt_result.rssi,
810                             rttResultsV3[currentIdx]->rtt_result.rtt_result.rx_rate.bitrate * 100,
811                             (unsigned long)rttResultsV3[currentIdx]->rtt_result.rtt_result.rtt,
812                             (unsigned long)rttResultsV3[currentIdx]->rtt_result.rtt_result.rtt_sd,
813                             rttResultsV3[currentIdx]->rtt_result.rtt_result.distance_mm,
814                             rttResultsV3[currentIdx]->rtt_result.rtt_result.burst_duration,
815                             rttResultsV3[currentIdx]->rtt_result.frequency,
816                             rttResultsV3[currentIdx]->rtt_result.packet_bw,
817                             rttResultsV3[currentIdx]->rtt_result.rtt_result.negotiated_burst_num);
818 
819             }
820         }
821 
822         if (mCompleted) {
823             unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
824             {
825                 if (*rttHandler.on_rtt_results_v3) {
826                     (*rttHandler.on_rtt_results_v3)(id(), totalCnt, rttResultsV3);
827                 }
828             }
829 
830             for (int i = 0; i < currentIdx; i++) {
831                 free(rttResultsV1[i]);
832                 rttResultsV1[i] = NULL;
833 
834                 free(rttResultsV2[i]);
835                 rttResultsV2[i] = NULL;
836 
837                 free(rttResultsV3[i]);
838                 rttResultsV3[i] = NULL;
839             }
840             totalCnt = currentIdx = nextidx = 0;
841             WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
842             if (cmd)
843                 cmd->releaseRef();
844         }
845         return NL_SKIP;
846     }
847 };
848 
849 
850 /* API to request RTT measurement */
wifi_rtt_range_request_v3(wifi_request_id id,wifi_interface_handle iface,unsigned num_rtt_config,wifi_rtt_config_v3 rtt_config[],wifi_rtt_event_handler_v3 handler)851 wifi_error wifi_rtt_range_request_v3(wifi_request_id id, wifi_interface_handle iface,
852         unsigned num_rtt_config, wifi_rtt_config_v3 rtt_config[],
853         wifi_rtt_event_handler_v3 handler)
854 {
855     if (iface == NULL) {
856         ALOGE("wifi_rtt_range_request_v3: NULL iface pointer provided."
857                 " Exit.");
858         return WIFI_ERROR_INVALID_ARGS;
859     }
860 
861     wifi_handle handle = getWifiHandle(iface);
862     if (handle == NULL) {
863         ALOGE("wifi_rtt_range_request_v3: NULL handle pointer provided."
864             " Exit.");
865         return WIFI_ERROR_INVALID_ARGS;
866     }
867 
868     ALOGI("Rtt range_request; id = %d", id);
869     RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
870     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
871     wifi_error result = wifi_register_cmd(handle, id, cmd);
872     if (result != WIFI_SUCCESS) {
873         cmd->releaseRef();
874         return result;
875     }
876     result = (wifi_error)cmd->start();
877     if (result != WIFI_SUCCESS) {
878         wifi_unregister_cmd(handle, id);
879         cmd->releaseRef();
880         return result;
881     }
882     return result;
883 }
884 
885 /* API to cancel RTT measurements */
wifi_rtt_range_cancel(wifi_request_id id,wifi_interface_handle iface,unsigned num_devices,mac_addr addr[])886 wifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle iface,
887         unsigned num_devices, mac_addr addr[])
888 {
889    if (iface == NULL) {
890 	ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
891 		" Exit.");
892 	return WIFI_ERROR_INVALID_ARGS;
893    }
894 
895     wifi_handle handle = getWifiHandle(iface);
896     if (handle == NULL) {
897 	ALOGE("wifi_rtt_range_cancel: NULL handle pointer provided."
898 		" Exit.");
899 	return WIFI_ERROR_INVALID_ARGS;
900     }
901 
902     ALOGI("Rtt range_cancel_request; id = %d", id);
903     RttCommand *cmd = new RttCommand(iface, id);
904     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
905     cmd->cancel_specific(num_devices, addr);
906     wifi_unregister_cmd(handle, id);
907     cmd->releaseRef();
908     return WIFI_SUCCESS;
909 }
910 
911 /* API to get RTT capability */
wifi_get_rtt_capabilities_v3(wifi_interface_handle iface,wifi_rtt_capabilities_v3 * capabilities)912 wifi_error wifi_get_rtt_capabilities_v3(wifi_interface_handle iface,
913         wifi_rtt_capabilities_v3 *capabilities)
914 {
915     if (iface == NULL) {
916         ALOGE("wifi_get_rtt_capabilities_v3: NULL iface pointer provided."
917                 " Exit.");
918         return WIFI_ERROR_INVALID_ARGS;
919     }
920 
921     if (capabilities == NULL) {
922         ALOGE("wifi_get_rtt_capabilities_v3: NULL capabilities pointer provided."
923                 " Exit.");
924         return WIFI_ERROR_INVALID_ARGS;
925     }
926 
927     GetRttCapabilitiesCommand command(iface, capabilities);
928     return (wifi_error) command.requestResponse();
929 }
930 
931 /* API to get the responder information */
wifi_rtt_get_responder_info(wifi_interface_handle iface,wifi_rtt_responder * responderInfo)932 wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
933         wifi_rtt_responder* responderInfo)
934 {
935     if (iface == NULL) {
936 	ALOGE("wifi_rtt_get_responder_info: NULL iface pointer provided."
937 		" Exit.");
938 	return WIFI_ERROR_INVALID_ARGS;
939     }
940 
941     GetRttResponderInfoCommand command(iface, responderInfo);
942     return (wifi_error) command.requestResponse();
943 
944 }
945 
946 /**
947  * Enable RTT responder mode.
948  * channel_hint - hint of the channel information where RTT responder should be enabled on.
949  * max_duration_seconds - timeout of responder mode.
950  * wifi_rtt_responder - information for RTT responder e.g. channel used and preamble supported.
951  */
wifi_enable_responder(wifi_request_id id,wifi_interface_handle iface,wifi_channel_info channel_hint,unsigned max_duration_seconds,wifi_rtt_responder * responderInfo)952 wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
953                                 wifi_channel_info channel_hint, unsigned max_duration_seconds,
954                                 wifi_rtt_responder* responderInfo)
955 {
956     EnableResponderCommand command(iface, id, channel_hint, max_duration_seconds, responderInfo);
957     return (wifi_error) command.requestResponse();
958 }
959 
960 /**
961  * Disable RTT responder mode.
962  */
wifi_disable_responder(wifi_request_id id,wifi_interface_handle iface)963 wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface)
964 {
965     CancelResponderCommand command(iface, id);
966     return (wifi_error) command.requestResponse();
967 }
968 
969