1 /* Copyright (c) 2014, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #define LOG_TAG "WifiHAL"
30 #include <cutils/sched_policy.h>
31 #include <unistd.h>
32
33 #include <utils/Log.h>
34 #include <time.h>
35
36 #include "common.h"
37 #include "cpp_bindings.h"
38 #include "rtt.h"
39 #include "wifi_hal.h"
40 #include "wifihal_internal.h"
41
42 /* Implementation of the API functions exposed in rtt.h */
wifi_get_rtt_capabilities(wifi_interface_handle iface,wifi_rtt_capabilities * capabilities)43 wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
44 wifi_rtt_capabilities *capabilities)
45 {
46 int ret = WIFI_SUCCESS;
47 lowi_cb_table_t *lowiWifiHalApi = NULL;
48
49 if (iface == NULL) {
50 ALOGE("wifi_get_rtt_capabilities: NULL iface pointer provided."
51 " Exit.");
52 return WIFI_ERROR_INVALID_ARGS;
53 }
54
55 interface_info *ifaceInfo = getIfaceInfo(iface);
56 wifi_handle wifiHandle = getWifiHandle(iface);
57
58 if (capabilities == NULL) {
59 ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided."
60 " Exit.");
61 return WIFI_ERROR_INVALID_ARGS;
62 }
63
64 /* RTT commands are diverted through LOWI interface. */
65 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
66 * LOWI if it isn't up yet.
67 */
68 lowiWifiHalApi = getLowiCallbackTable(
69 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
70 if (lowiWifiHalApi == NULL ||
71 lowiWifiHalApi->get_rtt_capabilities == NULL) {
72 ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or "
73 "the function pointer is NULL. Exit.");
74 ret = WIFI_ERROR_NOT_SUPPORTED;
75 goto cleanup;
76 }
77
78 ret = lowiWifiHalApi->get_rtt_capabilities(iface, capabilities);
79 if (ret != WIFI_SUCCESS) {
80 ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities "
81 "returned error:%d. Exit.", ret);
82 goto cleanup;
83 }
84
85 cleanup:
86 return (wifi_error)ret;
87 }
88
89 /* API to request RTT measurement */
wifi_rtt_range_request(wifi_request_id id,wifi_interface_handle iface,unsigned num_rtt_config,wifi_rtt_config rtt_config[],wifi_rtt_event_handler handler)90 wifi_error wifi_rtt_range_request(wifi_request_id id,
91 wifi_interface_handle iface,
92 unsigned num_rtt_config,
93 wifi_rtt_config rtt_config[],
94 wifi_rtt_event_handler handler)
95 {
96 int ret = WIFI_SUCCESS;
97 lowi_cb_table_t *lowiWifiHalApi = NULL;
98
99 if (iface == NULL) {
100 ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
101 " Exit.");
102 return WIFI_ERROR_INVALID_ARGS;
103 }
104
105 interface_info *ifaceInfo = getIfaceInfo(iface);
106 wifi_handle wifiHandle = getWifiHandle(iface);
107
108 if (rtt_config == NULL) {
109 ALOGE("wifi_rtt_range_request: NULL rtt_config pointer provided."
110 " Exit.");
111 return WIFI_ERROR_INVALID_ARGS;
112 }
113
114 if (num_rtt_config <= 0) {
115 ALOGE("wifi_rtt_range_request: number of destination BSSIDs to "
116 "measure RTT on = 0. Exit.");
117 return WIFI_ERROR_INVALID_ARGS;
118 }
119
120 if (handler.on_rtt_results == NULL) {
121 ALOGE("wifi_rtt_range_request: NULL capabilities pointer provided."
122 " Exit.");
123 return WIFI_ERROR_INVALID_ARGS;
124 }
125
126 /* RTT commands are diverted through LOWI interface. */
127 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
128 * LOWI if it isn't up yet.
129 */
130 lowiWifiHalApi = getLowiCallbackTable(
131 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
132 if (lowiWifiHalApi == NULL ||
133 lowiWifiHalApi->rtt_range_request == NULL) {
134 ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or "
135 "the function pointer is NULL. Exit.");
136 ret = WIFI_ERROR_NOT_SUPPORTED;
137 goto cleanup;
138 }
139
140 ret = lowiWifiHalApi->rtt_range_request(id,
141 iface,
142 num_rtt_config,
143 rtt_config,
144 handler);
145 if (ret != WIFI_SUCCESS) {
146 ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request "
147 "returned error:%d. Exit.", ret);
148 goto cleanup;
149 }
150
151 cleanup:
152 return (wifi_error)ret;
153 }
154
155 /* API to cancel RTT measurements */
wifi_rtt_range_cancel(wifi_request_id id,wifi_interface_handle iface,unsigned num_devices,mac_addr addr[])156 wifi_error wifi_rtt_range_cancel(wifi_request_id id,
157 wifi_interface_handle iface,
158 unsigned num_devices,
159 mac_addr addr[])
160 {
161 int ret = WIFI_SUCCESS;
162 lowi_cb_table_t *lowiWifiHalApi = NULL;
163
164 if (iface == NULL) {
165 ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
166 " Exit.");
167 return WIFI_ERROR_INVALID_ARGS;
168 }
169
170 interface_info *ifaceInfo = getIfaceInfo(iface);
171 wifi_handle wifiHandle = getWifiHandle(iface);
172
173 if (addr == NULL) {
174 ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided."
175 " Exit.");
176 return WIFI_ERROR_INVALID_ARGS;
177 }
178
179 if (num_devices <= 0) {
180 ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to "
181 "measure RTT on = 0. Exit.");
182 return WIFI_ERROR_INVALID_ARGS;
183 }
184
185 /* RTT commands are diverted through LOWI interface. */
186 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
187 * LOWI if it isn't up yet.
188 */
189 lowiWifiHalApi = getLowiCallbackTable(
190 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
191 if (lowiWifiHalApi == NULL ||
192 lowiWifiHalApi->rtt_range_cancel == NULL) {
193 ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
194 "the function pointer is NULL. Exit.");
195 ret = WIFI_ERROR_NOT_SUPPORTED;
196 goto cleanup;
197 }
198
199 ret = lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
200 if (ret != WIFI_SUCCESS) {
201 ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel "
202 "returned error:%d. Exit.", ret);
203 goto cleanup;
204 }
205
206 cleanup:
207 return (wifi_error)ret;
208 }
209
210 // API to configure the LCI. Used in RTT Responder mode only
wifi_set_lci(wifi_request_id id,wifi_interface_handle iface,wifi_lci_information * lci)211 wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface,
212 wifi_lci_information *lci)
213 {
214 int ret = WIFI_SUCCESS;
215 lowi_cb_table_t *lowiWifiHalApi = NULL;
216
217 if (iface == NULL) {
218 ALOGE("%s: NULL iface pointer provided."
219 " Exit.", __FUNCTION__);
220 return WIFI_ERROR_INVALID_ARGS;
221 }
222
223 interface_info *ifaceInfo = getIfaceInfo(iface);
224 wifi_handle wifiHandle = getWifiHandle(iface);
225
226 if (lci == NULL) {
227 ALOGE("%s: NULL lci pointer provided."
228 " Exit.", __FUNCTION__);
229 return WIFI_ERROR_INVALID_ARGS;
230 }
231
232 /* RTT commands are diverted through LOWI interface. */
233 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
234 * LOWI if it isn't up yet.
235 */
236 lowiWifiHalApi = getLowiCallbackTable(
237 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
238 if (lowiWifiHalApi == NULL ||
239 lowiWifiHalApi->rtt_set_lci == NULL) {
240 ALOGE("%s: getLowiCallbackTable returned NULL or "
241 "the function pointer is NULL. Exit.", __FUNCTION__);
242 ret = WIFI_ERROR_NOT_SUPPORTED;
243 goto cleanup;
244 }
245
246 ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci);
247 if (ret != WIFI_SUCCESS) {
248 ALOGE("%s: returned error:%d. Exit.",
249 __FUNCTION__, ret);
250 goto cleanup;
251 }
252
253 cleanup:
254 return (wifi_error)ret;
255 }
256
257 // API to configure the LCR. Used in RTT Responder mode only.
wifi_set_lcr(wifi_request_id id,wifi_interface_handle iface,wifi_lcr_information * lcr)258 wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
259 wifi_lcr_information *lcr)
260 {
261 int ret = WIFI_SUCCESS;
262 lowi_cb_table_t *lowiWifiHalApi = NULL;
263
264 if (iface == NULL) {
265 ALOGE("%s: NULL iface pointer provided."
266 " Exit.", __FUNCTION__);
267 return WIFI_ERROR_INVALID_ARGS;
268 }
269
270 interface_info *ifaceInfo = getIfaceInfo(iface);
271 wifi_handle wifiHandle = getWifiHandle(iface);
272
273 if (lcr == NULL) {
274 ALOGE("%s: NULL lcr pointer provided."
275 " Exit.", __FUNCTION__);
276 return WIFI_ERROR_INVALID_ARGS;
277 }
278
279 /* RTT commands are diverted through LOWI interface. */
280 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
281 * LOWI if it isn't up yet.
282 */
283 lowiWifiHalApi = getLowiCallbackTable(
284 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
285 if (lowiWifiHalApi == NULL ||
286 lowiWifiHalApi->rtt_set_lcr == NULL) {
287 ALOGE("%s: getLowiCallbackTable returned NULL or "
288 "the function pointer is NULL. Exit.", __FUNCTION__);
289 ret = WIFI_ERROR_NOT_SUPPORTED;
290 goto cleanup;
291 }
292
293 ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr);
294 if (ret != WIFI_SUCCESS) {
295 ALOGE("%s: returned error:%d. Exit.",
296 __FUNCTION__, ret);
297 goto cleanup;
298 }
299
300 cleanup:
301 return (wifi_error)ret;
302 }
303
304 /*
305 * Get RTT responder information e.g. WiFi channel to enable responder on.
306 */
wifi_rtt_get_responder_info(wifi_interface_handle iface,wifi_rtt_responder * responder_info)307 wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
308 wifi_rtt_responder *responder_info)
309 {
310 int ret = WIFI_SUCCESS;
311 lowi_cb_table_t *lowiWifiHalApi = NULL;
312
313 if (iface == NULL || responder_info == NULL) {
314 ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface,
315 responder_info);
316 return WIFI_ERROR_INVALID_ARGS;
317 }
318
319 /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
320 lowiWifiHalApi = getLowiCallbackTable(
321 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
322 if (lowiWifiHalApi == NULL ||
323 lowiWifiHalApi->rtt_get_responder_info == NULL) {
324 ALOGE("%s: getLowiCallbackTable returned NULL or "
325 "the function pointer is NULL. Exit.", __FUNCTION__);
326 ret = WIFI_ERROR_NOT_SUPPORTED;
327 goto cleanup;
328 }
329
330 ret = lowiWifiHalApi->rtt_get_responder_info(iface, responder_info);
331 if (ret != WIFI_SUCCESS) {
332 ALOGE("%s: returned error:%d. Exit.",
333 __FUNCTION__, ret);
334 goto cleanup;
335 }
336
337 cleanup:
338 return (wifi_error)ret;
339 }
340
341 /**
342 * Enable RTT responder mode.
343 * channel_hint - hint of the channel information where RTT responder should
344 * be enabled on.
345 * max_duration_seconds - timeout of responder mode.
346 * responder_info - responder information e.g. channel used for RTT responder,
347 * NULL if responder is not enabled.
348 */
wifi_enable_responder(wifi_request_id id,wifi_interface_handle iface,wifi_channel_info channel_hint,unsigned max_duration_seconds,wifi_rtt_responder * responder_info)349 wifi_error wifi_enable_responder(wifi_request_id id,
350 wifi_interface_handle iface,
351 wifi_channel_info channel_hint,
352 unsigned max_duration_seconds,
353 wifi_rtt_responder *responder_info)
354 {
355 int ret = WIFI_SUCCESS;
356 lowi_cb_table_t *lowiWifiHalApi = NULL;
357
358 if (iface == NULL || responder_info == NULL) {
359 ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, responder_info);
360 return WIFI_ERROR_INVALID_ARGS;
361 }
362
363 /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
364 lowiWifiHalApi = getLowiCallbackTable(
365 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
366 if (lowiWifiHalApi == NULL ||
367 lowiWifiHalApi->enable_responder == NULL) {
368 ALOGE("%s: getLowiCallbackTable returned NULL or "
369 "the function pointer is NULL. Exit.", __FUNCTION__);
370 ret = WIFI_ERROR_NOT_SUPPORTED;
371 goto cleanup;
372 }
373
374 ret = lowiWifiHalApi->enable_responder(id, iface, channel_hint,
375 max_duration_seconds,
376 responder_info);
377 if (ret != WIFI_SUCCESS) {
378 ALOGE("%s: returned error:%d. Exit.",
379 __FUNCTION__, ret);
380 goto cleanup;
381 }
382
383 cleanup:
384 return (wifi_error)ret;
385 }
386
387
388 /**
389 * Disable RTT responder mode.
390 */
wifi_disable_responder(wifi_request_id id,wifi_interface_handle iface)391 wifi_error wifi_disable_responder(wifi_request_id id,
392 wifi_interface_handle iface)
393
394 {
395 int ret = WIFI_SUCCESS;
396 lowi_cb_table_t *lowiWifiHalApi = NULL;
397
398 if (iface == NULL) {
399 ALOGE("%s: iface : %p", __FUNCTION__, iface);
400 return WIFI_ERROR_INVALID_ARGS;
401 }
402
403 /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
404 lowiWifiHalApi = getLowiCallbackTable(
405 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
406 if (lowiWifiHalApi == NULL ||
407 lowiWifiHalApi->disable_responder == NULL) {
408 ALOGE("%s: getLowiCallbackTable returned NULL or "
409 "the function pointer is NULL. Exit.", __FUNCTION__);
410 ret = WIFI_ERROR_NOT_SUPPORTED;
411 goto cleanup;
412 }
413
414 ret = lowiWifiHalApi->disable_responder(id, iface);
415 if (ret != WIFI_SUCCESS) {
416 ALOGE("%s: returned error:%d. Exit.",
417 __FUNCTION__, ret);
418 goto cleanup;
419 }
420
421 cleanup:
422 return (wifi_error)ret;
423 }
424