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 if (capabilities == NULL) {
56 ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided."
57 " Exit.");
58 return WIFI_ERROR_INVALID_ARGS;
59 }
60
61 /* RTT commands are diverted through LOWI interface. */
62 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
63 * LOWI if it isn't up yet.
64 */
65 lowiWifiHalApi = getLowiCallbackTable(
66 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
67 if (lowiWifiHalApi == NULL ||
68 lowiWifiHalApi->get_rtt_capabilities == NULL) {
69 ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or "
70 "the function pointer is NULL. Exit.");
71 ret = WIFI_ERROR_NOT_SUPPORTED;
72 goto cleanup;
73 }
74
75 ret = lowiWifiHalApi->get_rtt_capabilities(iface, capabilities);
76 if (ret != WIFI_SUCCESS) {
77 ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities "
78 "returned error:%d. Exit.", ret);
79 goto cleanup;
80 }
81
82 cleanup:
83 return (wifi_error)ret;
84 }
85
86 /* 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)87 wifi_error wifi_rtt_range_request(wifi_request_id id,
88 wifi_interface_handle iface,
89 unsigned num_rtt_config,
90 wifi_rtt_config rtt_config[],
91 wifi_rtt_event_handler handler)
92 {
93 int ret = WIFI_SUCCESS;
94 lowi_cb_table_t *lowiWifiHalApi = NULL;
95
96 if (iface == NULL) {
97 ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
98 " Exit.");
99 return WIFI_ERROR_INVALID_ARGS;
100 }
101
102 if (rtt_config == NULL) {
103 ALOGE("wifi_rtt_range_request: NULL rtt_config pointer provided."
104 " Exit.");
105 return WIFI_ERROR_INVALID_ARGS;
106 }
107
108 if (num_rtt_config <= 0) {
109 ALOGE("wifi_rtt_range_request: number of destination BSSIDs to "
110 "measure RTT on = 0. Exit.");
111 return WIFI_ERROR_INVALID_ARGS;
112 }
113
114 if (handler.on_rtt_results == NULL) {
115 ALOGE("wifi_rtt_range_request: NULL capabilities pointer provided."
116 " Exit.");
117 return WIFI_ERROR_INVALID_ARGS;
118 }
119
120 /* RTT commands are diverted through LOWI interface. */
121 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
122 * LOWI if it isn't up yet.
123 */
124 lowiWifiHalApi = getLowiCallbackTable(
125 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
126 if (lowiWifiHalApi == NULL ||
127 lowiWifiHalApi->rtt_range_request == NULL) {
128 ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or "
129 "the function pointer is NULL. Exit.");
130 ret = WIFI_ERROR_NOT_SUPPORTED;
131 goto cleanup;
132 }
133
134 ret = lowiWifiHalApi->rtt_range_request(id,
135 iface,
136 num_rtt_config,
137 rtt_config,
138 handler);
139 if (ret != WIFI_SUCCESS) {
140 ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request "
141 "returned error:%d. Exit.", ret);
142 goto cleanup;
143 }
144
145 cleanup:
146 return (wifi_error)ret;
147 }
148
149 /* API to cancel RTT measurements */
wifi_rtt_range_cancel(wifi_request_id id,wifi_interface_handle iface,unsigned num_devices,mac_addr addr[])150 wifi_error wifi_rtt_range_cancel(wifi_request_id id,
151 wifi_interface_handle iface,
152 unsigned num_devices,
153 mac_addr addr[])
154 {
155 int ret = WIFI_SUCCESS;
156 lowi_cb_table_t *lowiWifiHalApi = NULL;
157
158 if (iface == NULL) {
159 ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
160 " Exit.");
161 return WIFI_ERROR_INVALID_ARGS;
162 }
163
164 if (addr == NULL) {
165 ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided."
166 " Exit.");
167 return WIFI_ERROR_INVALID_ARGS;
168 }
169
170 if (num_devices <= 0) {
171 ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to "
172 "measure RTT on = 0. Exit.");
173 return WIFI_ERROR_INVALID_ARGS;
174 }
175
176 /* RTT commands are diverted through LOWI interface. */
177 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
178 * LOWI if it isn't up yet.
179 */
180 lowiWifiHalApi = getLowiCallbackTable(
181 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
182 if (lowiWifiHalApi == NULL ||
183 lowiWifiHalApi->rtt_range_cancel == NULL) {
184 ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
185 "the function pointer is NULL. Exit.");
186 ret = WIFI_ERROR_NOT_SUPPORTED;
187 goto cleanup;
188 }
189
190 ret = lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
191 if (ret != WIFI_SUCCESS) {
192 ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel "
193 "returned error:%d. Exit.", ret);
194 goto cleanup;
195 }
196
197 cleanup:
198 return (wifi_error)ret;
199 }
200
201 // 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)202 wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface,
203 wifi_lci_information *lci)
204 {
205 int ret = WIFI_SUCCESS;
206 lowi_cb_table_t *lowiWifiHalApi = NULL;
207
208 if (iface == NULL) {
209 ALOGE("%s: NULL iface pointer provided."
210 " Exit.", __FUNCTION__);
211 return WIFI_ERROR_INVALID_ARGS;
212 }
213
214 if (lci == NULL) {
215 ALOGE("%s: NULL lci pointer provided."
216 " Exit.", __FUNCTION__);
217 return WIFI_ERROR_INVALID_ARGS;
218 }
219
220 /* RTT commands are diverted through LOWI interface. */
221 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
222 * LOWI if it isn't up yet.
223 */
224 lowiWifiHalApi = getLowiCallbackTable(
225 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
226 if (lowiWifiHalApi == NULL ||
227 lowiWifiHalApi->rtt_set_lci == NULL) {
228 ALOGE("%s: getLowiCallbackTable returned NULL or "
229 "the function pointer is NULL. Exit.", __FUNCTION__);
230 ret = WIFI_ERROR_NOT_SUPPORTED;
231 goto cleanup;
232 }
233
234 ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci);
235 if (ret != WIFI_SUCCESS) {
236 ALOGE("%s: returned error:%d. Exit.",
237 __FUNCTION__, ret);
238 goto cleanup;
239 }
240
241 cleanup:
242 return (wifi_error)ret;
243 }
244
245 // 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)246 wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
247 wifi_lcr_information *lcr)
248 {
249 int ret = WIFI_SUCCESS;
250 lowi_cb_table_t *lowiWifiHalApi = NULL;
251
252 if (iface == NULL) {
253 ALOGE("%s: NULL iface pointer provided."
254 " Exit.", __FUNCTION__);
255 return WIFI_ERROR_INVALID_ARGS;
256 }
257
258 if (lcr == NULL) {
259 ALOGE("%s: NULL lcr pointer provided."
260 " Exit.", __FUNCTION__);
261 return WIFI_ERROR_INVALID_ARGS;
262 }
263
264 /* RTT commands are diverted through LOWI interface. */
265 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
266 * LOWI if it isn't up yet.
267 */
268 lowiWifiHalApi = getLowiCallbackTable(
269 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
270 if (lowiWifiHalApi == NULL ||
271 lowiWifiHalApi->rtt_set_lcr == NULL) {
272 ALOGE("%s: getLowiCallbackTable returned NULL or "
273 "the function pointer is NULL. Exit.", __FUNCTION__);
274 ret = WIFI_ERROR_NOT_SUPPORTED;
275 goto cleanup;
276 }
277
278 ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr);
279 if (ret != WIFI_SUCCESS) {
280 ALOGE("%s: returned error:%d. Exit.",
281 __FUNCTION__, ret);
282 goto cleanup;
283 }
284
285 cleanup:
286 return (wifi_error)ret;
287 }
288
289 /*
290 * Get RTT responder information e.g. WiFi channel to enable responder on.
291 */
wifi_rtt_get_responder_info(wifi_interface_handle iface,wifi_rtt_responder * responder_info)292 wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
293 wifi_rtt_responder *responder_info)
294 {
295 int ret = WIFI_SUCCESS;
296 lowi_cb_table_t *lowiWifiHalApi = NULL;
297
298 if (iface == NULL || responder_info == NULL) {
299 ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface,
300 responder_info);
301 return WIFI_ERROR_INVALID_ARGS;
302 }
303
304 /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
305 lowiWifiHalApi = getLowiCallbackTable(
306 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
307 if (lowiWifiHalApi == NULL ||
308 lowiWifiHalApi->rtt_get_responder_info == NULL) {
309 ALOGE("%s: getLowiCallbackTable returned NULL or "
310 "the function pointer is NULL. Exit.", __FUNCTION__);
311 ret = WIFI_ERROR_NOT_SUPPORTED;
312 goto cleanup;
313 }
314
315 ret = lowiWifiHalApi->rtt_get_responder_info(iface, responder_info);
316 if (ret != WIFI_SUCCESS) {
317 ALOGE("%s: returned error:%d. Exit.",
318 __FUNCTION__, ret);
319 goto cleanup;
320 }
321
322 cleanup:
323 return (wifi_error)ret;
324 }
325
326 /**
327 * Enable RTT responder mode.
328 * channel_hint - hint of the channel information where RTT responder should
329 * be enabled on.
330 * max_duration_seconds - timeout of responder mode.
331 * responder_info - responder information e.g. channel used for RTT responder,
332 * NULL if responder is not enabled.
333 */
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)334 wifi_error wifi_enable_responder(wifi_request_id id,
335 wifi_interface_handle iface,
336 wifi_channel_info channel_hint,
337 unsigned max_duration_seconds,
338 wifi_rtt_responder *responder_info)
339 {
340 int ret = WIFI_SUCCESS;
341 lowi_cb_table_t *lowiWifiHalApi = NULL;
342
343 if (iface == NULL || responder_info == NULL) {
344 ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, responder_info);
345 return WIFI_ERROR_INVALID_ARGS;
346 }
347
348 /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
349 lowiWifiHalApi = getLowiCallbackTable(
350 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
351 if (lowiWifiHalApi == NULL ||
352 lowiWifiHalApi->enable_responder == NULL) {
353 ALOGE("%s: getLowiCallbackTable returned NULL or "
354 "the function pointer is NULL. Exit.", __FUNCTION__);
355 ret = WIFI_ERROR_NOT_SUPPORTED;
356 goto cleanup;
357 }
358
359 ret = lowiWifiHalApi->enable_responder(id, iface, channel_hint,
360 max_duration_seconds,
361 responder_info);
362 if (ret != WIFI_SUCCESS) {
363 ALOGE("%s: returned error:%d. Exit.",
364 __FUNCTION__, ret);
365 goto cleanup;
366 }
367
368 cleanup:
369 return (wifi_error)ret;
370 }
371
372
373 /**
374 * Disable RTT responder mode.
375 */
wifi_disable_responder(wifi_request_id id,wifi_interface_handle iface)376 wifi_error wifi_disable_responder(wifi_request_id id,
377 wifi_interface_handle iface)
378
379 {
380 int ret = WIFI_SUCCESS;
381 lowi_cb_table_t *lowiWifiHalApi = NULL;
382
383 if (iface == NULL) {
384 ALOGE("%s: iface : %p", __FUNCTION__, iface);
385 return WIFI_ERROR_INVALID_ARGS;
386 }
387
388 /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
389 lowiWifiHalApi = getLowiCallbackTable(
390 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
391 if (lowiWifiHalApi == NULL ||
392 lowiWifiHalApi->disable_responder == NULL) {
393 ALOGE("%s: getLowiCallbackTable returned NULL or "
394 "the function pointer is NULL. Exit.", __FUNCTION__);
395 ret = WIFI_ERROR_NOT_SUPPORTED;
396 goto cleanup;
397 }
398
399 ret = lowiWifiHalApi->disable_responder(id, iface);
400 if (ret != WIFI_SUCCESS) {
401 ALOGE("%s: returned error:%d. Exit.",
402 __FUNCTION__, ret);
403 goto cleanup;
404 }
405
406 cleanup:
407 return (wifi_error)ret;
408 }
409