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 ALOGD("wifi_get_rtt_capabilities: Entry");
50
51 if (iface == NULL) {
52 ALOGE("wifi_get_rtt_capabilities: NULL iface pointer provided."
53 " Exit.");
54 return WIFI_ERROR_INVALID_ARGS;
55 }
56
57 interface_info *ifaceInfo = getIfaceInfo(iface);
58 wifi_handle wifiHandle = getWifiHandle(iface);
59
60 if (capabilities == NULL) {
61 ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided."
62 " Exit.");
63 return WIFI_ERROR_INVALID_ARGS;
64 }
65
66 /* RTT commands are diverted through LOWI interface. */
67 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
68 * LOWI if it isn't up yet.
69 */
70 lowiWifiHalApi = getLowiCallbackTable(
71 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
72 if (lowiWifiHalApi == NULL ||
73 lowiWifiHalApi->get_rtt_capabilities == NULL) {
74 ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or "
75 "the function pointer is NULL. Exit.");
76 ret = WIFI_ERROR_NOT_SUPPORTED;
77 goto cleanup;
78 }
79
80 ret = lowiWifiHalApi->get_rtt_capabilities(iface, capabilities);
81 if (ret != WIFI_SUCCESS) {
82 ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities "
83 "returned error:%d. Exit.", ret);
84 goto cleanup;
85 }
86
87 cleanup:
88 return (wifi_error)ret;
89 }
90
91 /* 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)92 wifi_error wifi_rtt_range_request(wifi_request_id id,
93 wifi_interface_handle iface,
94 unsigned num_rtt_config,
95 wifi_rtt_config rtt_config[],
96 wifi_rtt_event_handler handler)
97 {
98 int ret = WIFI_SUCCESS;
99 lowi_cb_table_t *lowiWifiHalApi = NULL;
100
101 ALOGD("wifi_rtt_range_request: Entry");
102
103 if (iface == NULL) {
104 ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
105 " Exit.");
106 return WIFI_ERROR_INVALID_ARGS;
107 }
108
109 interface_info *ifaceInfo = getIfaceInfo(iface);
110 wifi_handle wifiHandle = getWifiHandle(iface);
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) {
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 ret = WIFI_ERROR_NOT_SUPPORTED;
141 goto cleanup;
142 }
143
144 ret = lowiWifiHalApi->rtt_range_request(id,
145 iface,
146 num_rtt_config,
147 rtt_config,
148 handler);
149 if (ret != WIFI_SUCCESS) {
150 ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request "
151 "returned error:%d. Exit.", ret);
152 goto cleanup;
153 }
154
155 cleanup:
156 return (wifi_error)ret;
157 }
158
159 /* API to cancel RTT measurements */
wifi_rtt_range_cancel(wifi_request_id id,wifi_interface_handle iface,unsigned num_devices,mac_addr addr[])160 wifi_error wifi_rtt_range_cancel(wifi_request_id id,
161 wifi_interface_handle iface,
162 unsigned num_devices,
163 mac_addr addr[])
164 {
165 int ret = WIFI_SUCCESS;
166 lowi_cb_table_t *lowiWifiHalApi = NULL;
167
168 ALOGD("wifi_rtt_range_cancel: Entry");
169
170 if (iface == NULL) {
171 ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
172 " Exit.");
173 return WIFI_ERROR_INVALID_ARGS;
174 }
175
176 interface_info *ifaceInfo = getIfaceInfo(iface);
177 wifi_handle wifiHandle = getWifiHandle(iface);
178
179 if (addr == NULL) {
180 ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided."
181 " Exit.");
182 return WIFI_ERROR_INVALID_ARGS;
183 }
184
185 if (num_devices <= 0) {
186 ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to "
187 "measure RTT on = 0. Exit.");
188 return WIFI_ERROR_INVALID_ARGS;
189 }
190
191 /* RTT commands are diverted through LOWI interface. */
192 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
193 * LOWI if it isn't up yet.
194 */
195 lowiWifiHalApi = getLowiCallbackTable(
196 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
197 if (lowiWifiHalApi == NULL ||
198 lowiWifiHalApi->rtt_range_cancel == NULL) {
199 ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
200 "the function pointer is NULL. Exit.");
201 ret = WIFI_ERROR_NOT_SUPPORTED;
202 goto cleanup;
203 }
204
205 ret = lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
206 if (ret != WIFI_SUCCESS) {
207 ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel "
208 "returned error:%d. Exit.", ret);
209 goto cleanup;
210 }
211
212 cleanup:
213 return (wifi_error)ret;
214 }
215
216 // 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)217 wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface,
218 wifi_lci_information *lci)
219 {
220 int ret = WIFI_SUCCESS;
221 lowi_cb_table_t *lowiWifiHalApi = NULL;
222
223 ALOGD("%s: Entry", __FUNCTION__);
224
225 if (iface == NULL) {
226 ALOGE("%s: NULL iface pointer provided."
227 " Exit.", __FUNCTION__);
228 return WIFI_ERROR_INVALID_ARGS;
229 }
230
231 interface_info *ifaceInfo = getIfaceInfo(iface);
232 wifi_handle wifiHandle = getWifiHandle(iface);
233
234 if (lci == NULL) {
235 ALOGE("%s: NULL lci pointer provided."
236 " Exit.", __FUNCTION__);
237 return WIFI_ERROR_INVALID_ARGS;
238 }
239
240 /* RTT commands are diverted through LOWI interface. */
241 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
242 * LOWI if it isn't up yet.
243 */
244 lowiWifiHalApi = getLowiCallbackTable(
245 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
246 if (lowiWifiHalApi == NULL ||
247 lowiWifiHalApi->rtt_set_lci == NULL) {
248 ALOGE("%s: getLowiCallbackTable returned NULL or "
249 "the function pointer is NULL. Exit.", __FUNCTION__);
250 ret = WIFI_ERROR_NOT_SUPPORTED;
251 goto cleanup;
252 }
253
254 ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci);
255 if (ret != WIFI_SUCCESS) {
256 ALOGE("%s: returned error:%d. Exit.",
257 __FUNCTION__, ret);
258 goto cleanup;
259 }
260
261 cleanup:
262 return (wifi_error)ret;
263 }
264
265 // 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)266 wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
267 wifi_lcr_information *lcr)
268 {
269 int ret = WIFI_SUCCESS;
270 lowi_cb_table_t *lowiWifiHalApi = NULL;
271
272 ALOGD("%s: Entry", __FUNCTION__);
273
274 if (iface == NULL) {
275 ALOGE("%s: NULL iface pointer provided."
276 " Exit.", __FUNCTION__);
277 return WIFI_ERROR_INVALID_ARGS;
278 }
279
280 interface_info *ifaceInfo = getIfaceInfo(iface);
281 wifi_handle wifiHandle = getWifiHandle(iface);
282
283 if (lcr == NULL) {
284 ALOGE("%s: NULL lcr pointer provided."
285 " Exit.", __FUNCTION__);
286 return WIFI_ERROR_INVALID_ARGS;
287 }
288
289 /* RTT commands are diverted through LOWI interface. */
290 /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
291 * LOWI if it isn't up yet.
292 */
293 lowiWifiHalApi = getLowiCallbackTable(
294 ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
295 if (lowiWifiHalApi == NULL ||
296 lowiWifiHalApi->rtt_set_lcr == NULL) {
297 ALOGE("%s: getLowiCallbackTable returned NULL or "
298 "the function pointer is NULL. Exit.", __FUNCTION__);
299 ret = WIFI_ERROR_NOT_SUPPORTED;
300 goto cleanup;
301 }
302
303 ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr);
304 if (ret != WIFI_SUCCESS) {
305 ALOGE("%s: returned error:%d. Exit.",
306 __FUNCTION__, ret);
307 goto cleanup;
308 }
309
310 cleanup:
311 return (wifi_error)ret;
312 }
313
314