• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <hardware_legacy/rtt.h>
39 #include <hardware_legacy/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     hal_info *info = NULL;
92 
93     if (iface == NULL) {
94         ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
95             " Exit.");
96         return WIFI_ERROR_INVALID_ARGS;
97     }
98 
99     wifi_handle wifiHandle = getWifiHandle(iface);
100     info = getHalInfo(wifiHandle);
101     if (!info)
102     {
103         ALOGE("%s: hal_info is null ", __FUNCTION__);
104         return WIFI_ERROR_INVALID_ARGS;
105     }
106 
107     if (!(info->supported_feature_set & WIFI_FEATURE_D2AP_RTT)) {
108         ALOGE("%s: RTT is not supported by driver", __FUNCTION__);
109         return WIFI_ERROR_NOT_SUPPORTED;
110     }
111 
112     if (rtt_config == NULL) {
113         ALOGE("wifi_rtt_range_request: NULL rtt_config pointer provided."
114             " Exit.");
115         return WIFI_ERROR_INVALID_ARGS;
116     }
117 
118     if (num_rtt_config <= 0) {
119         ALOGE("wifi_rtt_range_request: number of destination BSSIDs to "
120             "measure RTT on = 0. Exit.");
121         return WIFI_ERROR_INVALID_ARGS;
122     }
123 
124     if (handler.on_rtt_results == NULL && handler.on_rtt_results_v2 == NULL ) {
125         ALOGE("wifi_rtt_range_request: NULL capabilities pointer provided."
126             " Exit.");
127         return WIFI_ERROR_INVALID_ARGS;
128     }
129 
130     /* RTT commands are diverted through LOWI interface. */
131     /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
132      * LOWI if it isn't up yet.
133      */
134     lowiWifiHalApi = getLowiCallbackTable(
135                     ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
136     if (lowiWifiHalApi == NULL ||
137         lowiWifiHalApi->rtt_range_request == NULL) {
138         ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or "
139             "the function pointer is NULL. Exit.");
140         return WIFI_ERROR_NOT_SUPPORTED;
141     }
142 
143     ret = (wifi_error)lowiWifiHalApi->rtt_range_request(id, iface,
144                                                         num_rtt_config,
145                                                         rtt_config, handler);
146     if (ret != WIFI_SUCCESS)
147         ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request "
148             "returned error:%d. Exit.", ret);
149 
150     return ret;
151 }
152 
153 /* API to cancel RTT measurements */
wifi_rtt_range_cancel(wifi_request_id id,wifi_interface_handle iface,unsigned num_devices,mac_addr addr[])154 wifi_error wifi_rtt_range_cancel(wifi_request_id id,
155                                    wifi_interface_handle iface,
156                                    unsigned num_devices,
157                                    mac_addr addr[])
158 {
159     wifi_error ret;
160     lowi_cb_table_t *lowiWifiHalApi = NULL;
161 
162     if (iface == NULL) {
163         ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
164             " Exit.");
165         return WIFI_ERROR_INVALID_ARGS;
166     }
167 
168     if (addr == NULL) {
169         ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided."
170             " Exit.");
171         return WIFI_ERROR_INVALID_ARGS;
172     }
173 
174     if (num_devices <= 0) {
175         ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to "
176             "measure RTT on = 0. Exit.");
177         return WIFI_ERROR_INVALID_ARGS;
178     }
179 
180     /* RTT commands are diverted through LOWI interface. */
181     /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
182      * LOWI if it isn't up yet.
183      */
184     lowiWifiHalApi = getLowiCallbackTable(
185                     ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
186     if (lowiWifiHalApi == NULL ||
187         lowiWifiHalApi->rtt_range_cancel == NULL) {
188         ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
189             "the function pointer is NULL. Exit.");
190         return WIFI_ERROR_NOT_SUPPORTED;
191     }
192 
193     ret = (wifi_error)lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
194     if (ret != WIFI_SUCCESS)
195         ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel "
196             "returned error:%d. Exit.", ret);
197 
198     return 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     wifi_error ret;
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         return WIFI_ERROR_NOT_SUPPORTED;
231     }
232 
233     ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci);
234     if (ret != WIFI_SUCCESS)
235         ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
236 
237     return ret;
238 }
239 
240 // 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)241 wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
242                         wifi_lcr_information *lcr)
243 {
244     wifi_error ret;
245     lowi_cb_table_t *lowiWifiHalApi = NULL;
246 
247     if (iface == NULL) {
248         ALOGE("%s: NULL iface pointer provided."
249             " Exit.", __FUNCTION__);
250         return WIFI_ERROR_INVALID_ARGS;
251     }
252 
253     if (lcr == NULL) {
254         ALOGE("%s: NULL lcr pointer provided."
255             " Exit.", __FUNCTION__);
256         return WIFI_ERROR_INVALID_ARGS;
257     }
258 
259     /* RTT commands are diverted through LOWI interface. */
260     /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
261      * LOWI if it isn't up yet.
262      */
263     lowiWifiHalApi = getLowiCallbackTable(
264                     ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
265     if (lowiWifiHalApi == NULL ||
266         lowiWifiHalApi->rtt_set_lcr == NULL) {
267         ALOGE("%s: getLowiCallbackTable returned NULL or "
268             "the function pointer is NULL. Exit.", __FUNCTION__);
269         return WIFI_ERROR_NOT_SUPPORTED;
270     }
271 
272     ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr);
273     if (ret != WIFI_SUCCESS)
274         ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
275 
276     return ret;
277 }
278 
279 /*
280  * Get RTT responder information e.g. WiFi channel to enable responder on.
281  */
wifi_rtt_get_responder_info(wifi_interface_handle iface,wifi_rtt_responder * responder_info)282 wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
283                                       wifi_rtt_responder *responder_info)
284 {
285     wifi_error ret;
286     lowi_cb_table_t *lowiWifiHalApi = NULL;
287 
288     if (iface == NULL || responder_info == NULL) {
289         ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface,
290                responder_info);
291         return WIFI_ERROR_INVALID_ARGS;
292     }
293 
294     /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
295     lowiWifiHalApi = getLowiCallbackTable(
296                     ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
297     if (lowiWifiHalApi == NULL ||
298         lowiWifiHalApi->rtt_get_responder_info == NULL) {
299         ALOGE("%s: getLowiCallbackTable returned NULL or "
300             "the function pointer is NULL. Exit.", __FUNCTION__);
301         return WIFI_ERROR_NOT_SUPPORTED;
302     }
303 
304     ret = lowiWifiHalApi->rtt_get_responder_info(iface, responder_info);
305     if (ret != WIFI_SUCCESS)
306         ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
307 
308     return ret;
309 }
310 
311 /**
312  * Enable RTT responder mode.
313  * channel_hint - hint of the channel information where RTT responder should
314  *                be enabled on.
315  * max_duration_seconds - timeout of responder mode.
316  * responder_info - responder information e.g. channel used for RTT responder,
317  *                  NULL if responder is not enabled.
318  */
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)319 wifi_error wifi_enable_responder(wifi_request_id id,
320                                  wifi_interface_handle iface,
321                                  wifi_channel_info channel_hint,
322                                  unsigned max_duration_seconds,
323                                  wifi_rtt_responder *responder_info)
324 {
325     wifi_error ret;
326     lowi_cb_table_t *lowiWifiHalApi = NULL;
327 
328     if (iface == NULL || responder_info == NULL) {
329         ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, responder_info);
330         return WIFI_ERROR_INVALID_ARGS;
331     }
332 
333     /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
334     lowiWifiHalApi = getLowiCallbackTable(
335                     ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
336     if (lowiWifiHalApi == NULL ||
337         lowiWifiHalApi->enable_responder == NULL) {
338         ALOGE("%s: getLowiCallbackTable returned NULL or "
339             "the function pointer is NULL. Exit.", __FUNCTION__);
340         return WIFI_ERROR_NOT_SUPPORTED;
341     }
342 
343     ret = lowiWifiHalApi->enable_responder(id, iface, channel_hint,
344                                            max_duration_seconds,
345                                            responder_info);
346     if (ret != WIFI_SUCCESS)
347         ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
348 
349     return ret;
350 }
351 
352 
353 /**
354  * Disable RTT responder mode.
355  */
wifi_disable_responder(wifi_request_id id,wifi_interface_handle iface)356 wifi_error wifi_disable_responder(wifi_request_id id,
357                                   wifi_interface_handle iface)
358 
359 {
360     wifi_error ret;
361     lowi_cb_table_t *lowiWifiHalApi = NULL;
362 
363     if (iface == NULL) {
364         ALOGE("%s: iface : %p", __FUNCTION__, iface);
365         return WIFI_ERROR_INVALID_ARGS;
366     }
367 
368     /* Open LOWI dynamic library, retrieve handler to LOWI APIs */
369     lowiWifiHalApi = getLowiCallbackTable(
370                     ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
371     if (lowiWifiHalApi == NULL ||
372         lowiWifiHalApi->disable_responder == NULL) {
373         ALOGE("%s: getLowiCallbackTable returned NULL or "
374             "the function pointer is NULL. Exit.", __FUNCTION__);
375         return WIFI_ERROR_NOT_SUPPORTED;
376     }
377 
378     ret = lowiWifiHalApi->disable_responder(id, iface);
379     if (ret != WIFI_SUCCESS)
380         ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
381 
382     return ret;
383 }
384