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