3 #include <sys/socket.h>
4 #include <netlink/genl/genl.h>
5 #include <netlink/genl/family.h>
6 #include <netlink/genl/ctrl.h>
7 #include <linux/rtnetlink.h>
8 #include <netpacket/packet.h>
9 #include <linux/filter.h>
10 #include <linux/errqueue.h>
12 #include <linux/pkt_sched.h>
13 #include <netlink/object-api.h>
14 #include <netlink/netlink.h>
15 #include <netlink/socket.h>
18 #include "nl80211_copy.h"
22 #include <utils/Log.h>
26 #include "cpp_bindings.h"
30 SLSI_RTT_ATTRIBUTE_TARGET_CNT
= 0,
31 SLSI_RTT_ATTRIBUTE_TARGET_INFO
,
32 SLSI_RTT_ATTRIBUTE_TARGET_MAC
,
33 SLSI_RTT_ATTRIBUTE_TARGET_TYPE
,
34 SLSI_RTT_ATTRIBUTE_TARGET_PEER
,
35 SLSI_RTT_ATTRIBUTE_TARGET_CHAN_WIDTH
,
36 SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ
,
37 SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ0
,
38 SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ1
,
39 SLSI_RTT_ATTRIBUTE_TARGET_PERIOD
,
40 SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST
,
41 SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST
,
42 SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM
,
43 SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR
,
44 SLSI_RTT_ATTRIBUTE_TARGET_LCI
,
45 SLSI_RTT_ATTRIBUTE_TARGET_LCR
,
46 SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION
,
47 SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE
,
48 SLSI_RTT_ATTRIBUTE_TARGET_BW
,
49 SLSI_RTT_ATTRIBUTE_RESULTS_COMPLETE
= 30,
50 SLSI_RTT_ATTRIBUTE_RESULTS_PER_TARGET
,
51 SLSI_RTT_ATTRIBUTE_RESULT_CNT
,
52 SLSI_RTT_ATTRIBUTE_RESULT
,
53 SLSI_RTT_ATTRIBUTE_TARGET_ID
56 enum slsi_rtt_event_attributes
{
57 SLSI_RTT_EVENT_ATTR_ADDR
= 0,
58 SLSI_RTT_EVENT_ATTR_BURST_NUM
,
59 SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM
,
60 SLSI_RTT_EVENT_ATTR_SUCCESS_NUM
,
61 SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER
,
62 SLSI_RTT_EVENT_ATTR_STATUS
,
63 SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION
,
64 SLSI_RTT_EVENT_ATTR_TYPE
,
65 SLSI_RTT_EVENT_ATTR_RSSI
,
66 SLSI_RTT_EVENT_ATTR_RSSI_SPREAD
,
67 SLSI_RTT_EVENT_ATTR_TX_PREAMBLE
,
68 SLSI_RTT_EVENT_ATTR_TX_NSS
,
69 SLSI_RTT_EVENT_ATTR_TX_BW
,
70 SLSI_RTT_EVENT_ATTR_TX_MCS
,
71 SLSI_RTT_EVENT_ATTR_TX_RATE
,
72 SLSI_RTT_EVENT_ATTR_RX_PREAMBLE
,
73 SLSI_RTT_EVENT_ATTR_RX_NSS
,
74 SLSI_RTT_EVENT_ATTR_RX_BW
,
75 SLSI_RTT_EVENT_ATTR_RX_MCS
,
76 SLSI_RTT_EVENT_ATTR_RX_RATE
,
77 SLSI_RTT_EVENT_ATTR_RTT
,
78 SLSI_RTT_EVENT_ATTR_RTT_SD
,
79 SLSI_RTT_EVENT_ATTR_RTT_SPREAD
,
80 SLSI_RTT_EVENT_ATTR_DISTANCE_MM
,
81 SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM
,
82 SLSI_RTT_EVENT_ATTR_DISTANCE_SPREAD_MM
,
83 SLSI_RTT_EVENT_ATTR_TIMESTAMP_US
,
84 SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN
,
85 SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM
,
86 SLSI_RTT_EVENT_ATTR_LCI
,
87 SLSI_RTT_EVENT_ATTR_LCR
96 } __attribute__ ((packed
));
97 typedef struct dot11_rm_ie dot11_rm_ie_t
;
98 typedef struct strmap_entry
{
103 static const strmap_entry_t err_info
[] = {
104 {RTT_STATUS_SUCCESS
, string("Success")},
105 {RTT_STATUS_FAILURE
, string("Failure")},
106 {RTT_STATUS_FAIL_NO_RSP
, string("No reponse")},
107 {RTT_STATUS_FAIL_INVALID_TS
, string("Invalid Timestamp")},
108 {RTT_STATUS_FAIL_PROTOCOL
, string("Protocol error")},
109 {RTT_STATUS_FAIL_REJECTED
, string("Rejected")},
110 {RTT_STATUS_FAIL_NOT_SCHEDULED_YET
, string("not scheduled")},
111 {RTT_STATUS_FAIL_SCHEDULE
, string("schedule failed")},
112 {RTT_STATUS_FAIL_TM_TIMEOUT
, string("timeout")},
113 {RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL
, string("AP is on difference channel")},
114 {RTT_STATUS_FAIL_NO_CAPABILITY
, string("no capability")},
115 {RTT_STATUS_FAIL_BUSY_TRY_LATER
, string("busy and try later")},
116 {RTT_STATUS_ABORTED
, string("aborted")}
118 /*static const string get_err_info(int status)
121 const strmap_entry_t *p_entry;
122 int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
123 * scan thru the table till end
125 for (i = 0; i < (int) num_entries; i++)
127 if (p_entry->id == status)
128 return p_entry->text;
129 p_entry++; * next entry
131 return "unknown error"; * not found
133 class RttCommand
: public WifiCommand
136 unsigned numTargetDevice
;
140 static const int MAX_RESULTS
= 1024;
141 wifi_rtt_result
*rttResults
[MAX_RESULTS
];
142 wifi_rtt_config
*rttParams
;
143 wifi_rtt_event_handler rttHandler
;
145 RttCommand(wifi_interface_handle iface
, int id
, unsigned num_rtt_config
,
146 wifi_rtt_config rtt_config
[], wifi_rtt_event_handler handler
)
147 : WifiCommand(iface
, id
), rtt_id(id
), numTargetDevice(num_rtt_config
), rttParams(rtt_config
),
150 memset(rttResults
, 0, sizeof(rttResults
));
156 RttCommand(wifi_interface_handle iface
, int id
)
157 : WifiCommand(iface
, id
)
164 int createSetupRequest(WifiRequest
& request
) {
165 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START
);
169 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
170 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_ID
, rtt_id
);
174 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_CNT
, numTargetDevice
);
175 ALOGI("numTargetDevice %d\n",numTargetDevice
);
179 nlattr
*rtt_config
= request
.attr_start(SLSI_RTT_ATTRIBUTE_TARGET_INFO
);
180 for (unsigned i
= 0; i
< numTargetDevice
; i
++) {
181 nlattr
*attr2
= request
.attr_start(i
);
183 result
= request
.put_addr(SLSI_RTT_ATTRIBUTE_TARGET_MAC
, rttParams
[i
].addr
);
184 ALOGI("mac_addr %p\n",rttParams
[i
].addr
);
189 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_TYPE
, rttParams
[i
].type
);
190 ALOGI("\trtt_type %d\n",rttParams
[i
].type
);
195 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_PEER
, rttParams
[i
].peer
);
196 ALOGI("\trtt_peer %d\n",rttParams
[i
].peer
);
200 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ
, rttParams
[i
].channel
.center_freq
);
201 ALOGI("\trtt_ primary channel_freq %d\n",rttParams
[i
].channel
.center_freq
);
205 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_WIDTH
, rttParams
[i
].channel
.width
);
206 ALOGI("\trtt_channel width:%d\n",rttParams
[i
].channel
.width
);
210 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ0
, rttParams
[i
].channel
.center_freq0
);
211 ALOGI("\trtt_channel_freq 0:%d\n",rttParams
[i
].channel
.center_freq0
);
215 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ1
, rttParams
[i
].channel
.center_freq1
);
216 ALOGI("\trtt_channel_freq 1: %d\n",rttParams
[i
].channel
.center_freq1
);
220 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST
, rttParams
[i
].num_burst
);
221 ALOGI("\tnum_burst %d\n",rttParams
[i
].num_burst
);
226 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST
,
227 rttParams
[i
].num_frames_per_burst
);
228 ALOGI("\tnum_frames_per_burst %d\n",rttParams
[i
].num_frames_per_burst
);
233 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM
,
234 rttParams
[i
].num_retries_per_rtt_frame
);
235 ALOGI("\tnum_retries_per_rtt_frame %d\n",rttParams
[i
].num_retries_per_rtt_frame
);
240 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR
,
241 rttParams
[i
].num_retries_per_ftmr
);
242 ALOGI("\tnum_retries_per_ftmr %d\n",rttParams
[i
].num_retries_per_ftmr
);
247 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_PERIOD
,
248 rttParams
[i
].burst_period
);
249 ALOGI("\tburst_period %d\n",rttParams
[i
].burst_period
);
254 result
= request
.put_u8(SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION
,
255 rttParams
[i
].burst_duration
);
256 ALOGI("\tburst_duration %d\n",rttParams
[i
].burst_duration
);
261 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_LCI
,
262 rttParams
[i
].LCI_request
);
263 ALOGI("\tLCI_request %d\n",rttParams
[i
].LCI_request
);
268 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_LCR
,
269 rttParams
[i
].LCR_request
);
270 ALOGI("\tLCR_ request%d\n",rttParams
[i
].LCR_request
);
275 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_BW
,
277 ALOGI("\tBW%d\n",rttParams
[i
].bw
);
282 result
= request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE
,
283 rttParams
[i
].preamble
);
284 ALOGI("\tpreamble%d\n",rttParams
[i
].preamble
);
288 request
.attr_end(attr2
);
290 ALOGE("setup request created");
291 request
.attr_end(rtt_config
);
292 request
.attr_end(data
);
296 int createTeardownRequest(WifiRequest
& request
, unsigned num_devices
, mac_addr addr
[]) {
297 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL
);
301 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
302 request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_ID
, rtt_id
);
303 request
.put_u16(SLSI_RTT_ATTRIBUTE_TARGET_CNT
, num_devices
);
304 for(unsigned i
= 0; i
< num_devices
; i
++) {
305 result
= request
.put_addr(SLSI_RTT_ATTRIBUTE_TARGET_MAC
, addr
[i
]);
310 request
.attr_end(data
);
314 WifiRequest
request(familyId(), ifaceId());
315 int result
= createSetupRequest(request
);
316 if (result
!= WIFI_SUCCESS
) {
317 ALOGE("failed to create setup request; result = %d", result
);
321 result
= requestResponse(request
);
322 if (result
!= WIFI_SUCCESS
) {
323 ALOGE("failed to configure RTT setup; result = %d", result
);
326 registerVendorHandler(GOOGLE_OUI
, SLSI_RTT_RESULT_EVENT
);
327 registerVendorHandler(GOOGLE_OUI
, SLSI_RTT_EVENT_COMPLETE
);
331 virtual int cancel() {
332 ALOGD("Stopping RTT");
334 WifiRequest
request(familyId(), ifaceId());
335 int result
= createTeardownRequest(request
, 0, NULL
);
336 if (result
!= WIFI_SUCCESS
) {
337 ALOGE("failed to create stop request; result = %d", result
);
339 result
= requestResponse(request
);
340 if (result
!= WIFI_SUCCESS
) {
341 ALOGE("failed to stop scan; result = %d", result
);
344 ALOGE("RTT stopped");
345 /*This needs to be check */
346 unregisterVendorHandler(GOOGLE_OUI
, SLSI_RTT_RESULT_EVENT
);
347 unregisterVendorHandler(GOOGLE_OUI
, SLSI_RTT_EVENT_COMPLETE
);
351 int cancel_specific(unsigned num_devices
, mac_addr addr
[]) {
352 ALOGE("Stopping RTT specific");
354 WifiRequest
request(familyId(), ifaceId());
355 int result
= createTeardownRequest(request
, num_devices
, addr
);
356 if (result
!= WIFI_SUCCESS
) {
357 ALOGE("failed to create stop request; result = %d", result
);
359 result
= requestResponse(request
);
360 if (result
!= WIFI_SUCCESS
) {
361 ALOGE("failed to stop RTT; result = %d", result
);
364 ALOGE("Specific RTT stopped");
365 /*This needs to be check */
366 unregisterVendorHandler(GOOGLE_OUI
, SLSI_RTT_RESULT_EVENT
);
367 unregisterVendorHandler(GOOGLE_OUI
, SLSI_RTT_EVENT_COMPLETE
);
371 virtual int handleResponse(WifiEvent
& reply
) {
372 /* Nothing to do on response! */
376 virtual int handleEvent(WifiEvent
& event
) {
378 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
379 int event_id
= event
.get_vendor_subcmd();
380 ALOGD("Got an RTT event with id:%d\n",event_id
);
381 if(event_id
== SLSI_RTT_EVENT_COMPLETE
) {
382 ALOGD("RTT event complete\n");
383 unregisterVendorHandler(GOOGLE_OUI
, SLSI_RTT_RESULT_EVENT
);
384 WifiCommand
*cmd
= wifi_unregister_cmd(wifiHandle(), id());
387 } else if (event_id
== SLSI_RTT_RESULT_EVENT
) {
390 ALOGD("RTT result event\n");
391 for (nl_iterator
it(vendor_data
); it
.has_next(); it
.next()) {
392 if (it
.get_type() == SLSI_RTT_ATTRIBUTE_RESULT_CNT
) {
393 result_cnt
= it
.get_u16();
394 ALOGD("RTT results count : %d\n", result_cnt
);
395 } else if (it
.get_type() == SLSI_RTT_ATTRIBUTE_TARGET_ID
) {
396 rtt_id
= it
.get_u16();
397 ALOGD("RTT target id : %d\n", rtt_id
);
398 } else if (it
.get_type() == SLSI_RTT_ATTRIBUTE_RESULT
) {
399 ALOGD("RTT result attribute : %d\n", SLSI_RTT_ATTRIBUTE_RESULT
);
400 rttResults
[currentIdx
] = (wifi_rtt_result
*)malloc(sizeof(wifi_rtt_result
));
401 wifi_rtt_result
*rtt_result
= rttResults
[currentIdx
];
402 if (rtt_result
== NULL
) {
403 ALOGE("failed to allocate the wifi_rtt_result\n");
404 unregisterVendorHandler(GOOGLE_OUI
, SLSI_RTT_RESULT_EVENT
);
407 for(nl_iterator
nl_nested_itr((struct nlattr
*)it
.get()); nl_nested_itr
.has_next(); nl_nested_itr
.next()) {
408 if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_ADDR
) {
409 memcpy(rtt_result
->addr
, nl_nested_itr
.get_data(), nl_nested_itr
.get_len());
410 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_BURST_NUM
) {
411 rtt_result
->burst_num
= (unsigned)nl_nested_itr
.get_u8();
412 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM
) {
413 rtt_result
->measurement_number
= (unsigned)nl_nested_itr
.get_u8();
414 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_SUCCESS_NUM
) {
415 rtt_result
->success_number
= (unsigned)nl_nested_itr
.get_u8();
416 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER
) {
417 rtt_result
->number_per_burst_peer
= (byte
)nl_nested_itr
.get_u8();
418 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_STATUS
) {
419 rtt_result
->status
= (wifi_rtt_status
)nl_nested_itr
.get_u16();
420 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION
) {
421 rtt_result
->retry_after_duration
= (byte
)nl_nested_itr
.get_u8();
422 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TYPE
) {
423 rtt_result
->type
= (wifi_rtt_type
)nl_nested_itr
.get_u16();
424 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RSSI
) {
425 rtt_result
->rssi
= (wifi_rssi
)nl_nested_itr
.get_u16();
426 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RSSI_SPREAD
) {
427 rtt_result
->rssi_spread
= (wifi_rssi
)nl_nested_itr
.get_u16();
428 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TX_PREAMBLE
) {
429 rtt_result
->tx_rate
.preamble
= nl_nested_itr
.get_u32();
430 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TX_NSS
) {
431 rtt_result
->tx_rate
.nss
= nl_nested_itr
.get_u32();
432 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TX_BW
) {
433 rtt_result
->tx_rate
.bw
= nl_nested_itr
.get_u32();
434 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TX_MCS
) {
435 rtt_result
->tx_rate
.rateMcsIdx
= nl_nested_itr
.get_u32();
436 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TX_RATE
) {
437 rtt_result
->tx_rate
.bitrate
= nl_nested_itr
.get_u32();
438 }else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RX_PREAMBLE
) {
439 rtt_result
->rx_rate
.preamble
= nl_nested_itr
.get_u32();
440 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RX_NSS
) {
441 rtt_result
->rx_rate
.nss
= nl_nested_itr
.get_u32();
442 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RX_BW
) {
443 rtt_result
->rx_rate
.bw
= nl_nested_itr
.get_u32();
444 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RX_MCS
) {
445 rtt_result
->rx_rate
.rateMcsIdx
= nl_nested_itr
.get_u32();
446 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RX_RATE
) {
447 rtt_result
->rx_rate
.bitrate
= nl_nested_itr
.get_u32();
448 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RTT
) {
449 rtt_result
->rtt
= (wifi_timespan
)nl_nested_itr
.get_u32();
450 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RTT_SD
) {
451 rtt_result
->rtt_sd
= (wifi_timespan
)nl_nested_itr
.get_u16();
452 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_RTT_SPREAD
) {
453 rtt_result
->rtt_spread
= (wifi_timespan
)nl_nested_itr
.get_u16();
454 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_DISTANCE_MM
) {
455 rtt_result
->distance_mm
= nl_nested_itr
.get_u32();
456 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM
) {
457 rtt_result
->distance_sd_mm
= nl_nested_itr
.get_u32();
458 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_DISTANCE_SPREAD_MM
) {
459 rtt_result
->distance_spread_mm
= nl_nested_itr
.get_u32();
460 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_TIMESTAMP_US
) {
461 rtt_result
->ts
= (wifi_timestamp
)nl_nested_itr
.get_u32();
462 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN
) {
463 rtt_result
->burst_duration
= nl_nested_itr
.get_u16();
464 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM
) {
465 rtt_result
->negotiated_burst_num
= nl_nested_itr
.get_u8();
466 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_LCI
) {
467 u8
*lci_ie
= (u8
*)nl_nested_itr
.get_data();
468 rtt_result
->LCI
= (wifi_information_element
*)malloc(sizeof(wifi_information_element
) + nl_nested_itr
.get_len() - 2);
469 rtt_result
->LCI
->id
= lci_ie
[0];
470 rtt_result
->LCI
->len
=lci_ie
[1];
471 memcpy(rtt_result
->LCI
->data
, &lci_ie
[2], nl_nested_itr
.get_len() - 2);
472 } else if (nl_nested_itr
.get_type() == SLSI_RTT_EVENT_ATTR_LCR
) {
473 u8
*lcr_ie
= (u8
*)nl_nested_itr
.get_data();
474 rtt_result
->LCR
= (wifi_information_element
*)malloc(sizeof(wifi_information_element
) + nl_nested_itr
.get_len() - 2);
475 rtt_result
->LCR
->id
= lcr_ie
[0];
476 rtt_result
->LCR
->len
=lcr_ie
[1];
477 memcpy(rtt_result
->LCR
->data
, &lcr_ie
[2], nl_nested_itr
.get_len() - 2);
483 (*rttHandler
.on_rtt_results
)(id() ,currentIdx
, rttResults
);
484 for (int i
= 0; i
< currentIdx
; i
++) {
486 rttResults
[i
] = NULL
;
490 ALOGE("Handled response for rtt config");
494 class GetRttCapabilitiesCommand
: public WifiCommand
496 wifi_rtt_capabilities
*mCapabilities
;
498 GetRttCapabilitiesCommand(wifi_interface_handle iface
, wifi_rtt_capabilities
*capabitlites
)
499 : WifiCommand(iface
, 0), mCapabilities(capabitlites
)
501 memset(mCapabilities
, 0, sizeof(*mCapabilities
));
504 virtual int create() {
505 int ret
= mMsg
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES
);
507 ALOGE("NL message creation failed");
514 virtual int handleResponse(WifiEvent
& reply
) {
516 if (reply
.get_cmd() != NL80211_CMD_VENDOR
) {
517 ALOGE("Ignoring reply with cmd = %d", reply
.get_cmd());
520 void *data
= reply
.get_vendor_data();
521 int len
= reply
.get_vendor_data_len();
523 memcpy(mCapabilities
, data
, min(len
, (int) sizeof(*mCapabilities
)));
524 ALOGE("RTT capa response");
528 /*class GetRttResponderInfoCommand : public WifiCommand
530 wifi_rtt_responder* mResponderInfo;
532 GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
533 : WifiCommand(iface, 0), mResponderInfo(responderInfo)
535 memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
539 virtual int create() {
540 ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
542 int ret = mMsg.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_RTT_GETAVAILCHANNEL);
551 virtual int handleResponse(WifiEvent& reply) {
553 ALOGD("In GetRttResponderInfoCommand::handleResponse");
555 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
556 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
560 int id = reply.get_vendor_id();
561 int subcmd = reply.get_vendor_subcmd();
563 void *data = reply.get_vendor_data();
564 int len = reply.get_vendor_data_len();
566 ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
567 sizeof(*mResponderInfo));
569 memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
575 /* API to request RTT measurement */
576 wifi_error
wifi_rtt_range_request(wifi_request_id id
, wifi_interface_handle iface
,
577 unsigned num_rtt_config
, wifi_rtt_config rtt_config
[], wifi_rtt_event_handler handler
)
579 ALOGE("Inside RTT RANGE range request");
580 wifi_handle handle
= getWifiHandle(iface
);
581 RttCommand
*cmd
= new RttCommand(iface
, id
, num_rtt_config
, rtt_config
, handler
);
582 NULL_CHECK_RETURN(cmd
, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY
);
583 wifi_error result
= wifi_register_cmd(handle
, id
, cmd
);
584 if (result
!= WIFI_SUCCESS
) {
588 result
= (wifi_error
)cmd
->start();
589 if (result
!= WIFI_SUCCESS
) {
590 wifi_unregister_cmd(handle
, id
);
594 ALOGE("wifi range request successfully executed");
598 /* API to cancel RTT measurements */
599 wifi_error
wifi_rtt_range_cancel(wifi_request_id id
, wifi_interface_handle iface
,
600 unsigned num_devices
, mac_addr addr
[])
603 return WIFI_ERROR_UNINITIALIZED
;
604 RttCommand
*cmd
= new RttCommand(iface
, id
);
605 NULL_CHECK_RETURN(cmd
, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY
);
606 cmd
->cancel_specific(num_devices
, addr
);
611 /* API to get RTT capability */
612 wifi_error
wifi_get_rtt_capabilities(wifi_interface_handle iface
,
613 wifi_rtt_capabilities
*capabilities
)
615 ALOGE("Inside get rtt capabilities cap:%p iface:%p", capabilities
, iface
);
617 return WIFI_ERROR_UNINITIALIZED
;
618 GetRttCapabilitiesCommand
command(iface
, capabilities
);
619 return (wifi_error
) command
.requestResponse();
622 /* API to get the responder information */
623 wifi_error
wifi_rtt_get_responder_info(wifi_interface_handle iface
,
624 wifi_rtt_responder
* responderInfo
)
626 /*GetRttResponderInfoCommand command(iface, responderInfo);
627 return (wifi_error) command.requestResponse();*/
628 return WIFI_ERROR_NOT_SUPPORTED
;