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 */ 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 */ 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 */ 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 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. 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 */ 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 */ 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 */ 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