• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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