You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
370 lines
13 KiB
370 lines
13 KiB
/* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of The Linux Foundation nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#define LOG_TAG "WifiHAL"
|
|
#include <cutils/sched_policy.h>
|
|
#include <unistd.h>
|
|
|
|
#include <utils/Log.h>
|
|
#include <time.h>
|
|
|
|
#include "common.h"
|
|
#include "cpp_bindings.h"
|
|
#include "rtt.h"
|
|
#include "wifi_hal.h"
|
|
#include "wifihal_internal.h"
|
|
|
|
/* Implementation of the API functions exposed in rtt.h */
|
|
wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
|
|
wifi_rtt_capabilities *capabilities)
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL) {
|
|
ALOGE("wifi_get_rtt_capabilities: NULL iface pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (capabilities == NULL) {
|
|
ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* RTT commands are diverted through LOWI interface. */
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
|
|
* LOWI if it isn't up yet.
|
|
*/
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->get_rtt_capabilities == NULL) {
|
|
ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.");
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = (wifi_error)lowiWifiHalApi->get_rtt_capabilities(iface, capabilities);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities "
|
|
"returned error:%d. Exit.", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* API to request RTT measurement */
|
|
wifi_error 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)
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL) {
|
|
ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (rtt_config == NULL) {
|
|
ALOGE("wifi_rtt_range_request: NULL rtt_config pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (num_rtt_config <= 0) {
|
|
ALOGE("wifi_rtt_range_request: number of destination BSSIDs to "
|
|
"measure RTT on = 0. Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (handler.on_rtt_results == NULL) {
|
|
ALOGE("wifi_rtt_range_request: NULL capabilities pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* RTT commands are diverted through LOWI interface. */
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
|
|
* LOWI if it isn't up yet.
|
|
*/
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->rtt_range_request == NULL) {
|
|
ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.");
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = (wifi_error)lowiWifiHalApi->rtt_range_request(id, iface,
|
|
num_rtt_config,
|
|
rtt_config, handler);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request "
|
|
"returned error:%d. Exit.", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* API to cancel RTT measurements */
|
|
wifi_error wifi_rtt_range_cancel(wifi_request_id id,
|
|
wifi_interface_handle iface,
|
|
unsigned num_devices,
|
|
mac_addr addr[])
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL) {
|
|
ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (addr == NULL) {
|
|
ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided."
|
|
" Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (num_devices <= 0) {
|
|
ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to "
|
|
"measure RTT on = 0. Exit.");
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* RTT commands are diverted through LOWI interface. */
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
|
|
* LOWI if it isn't up yet.
|
|
*/
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->rtt_range_cancel == NULL) {
|
|
ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.");
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = (wifi_error)lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel "
|
|
"returned error:%d. Exit.", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// API to configure the LCI. Used in RTT Responder mode only
|
|
wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface,
|
|
wifi_lci_information *lci)
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL) {
|
|
ALOGE("%s: NULL iface pointer provided."
|
|
" Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (lci == NULL) {
|
|
ALOGE("%s: NULL lci pointer provided."
|
|
" Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* RTT commands are diverted through LOWI interface. */
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
|
|
* LOWI if it isn't up yet.
|
|
*/
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->rtt_set_lci == NULL) {
|
|
ALOGE("%s: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// API to configure the LCR. Used in RTT Responder mode only.
|
|
wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface,
|
|
wifi_lcr_information *lcr)
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL) {
|
|
ALOGE("%s: NULL iface pointer provided."
|
|
" Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
if (lcr == NULL) {
|
|
ALOGE("%s: NULL lcr pointer provided."
|
|
" Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* RTT commands are diverted through LOWI interface. */
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize
|
|
* LOWI if it isn't up yet.
|
|
*/
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->rtt_set_lcr == NULL) {
|
|
ALOGE("%s: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Get RTT responder information e.g. WiFi channel to enable responder on.
|
|
*/
|
|
wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
|
|
wifi_rtt_responder *responder_info)
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL || responder_info == NULL) {
|
|
ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface,
|
|
responder_info);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs */
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->rtt_get_responder_info == NULL) {
|
|
ALOGE("%s: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = lowiWifiHalApi->rtt_get_responder_info(iface, responder_info);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Enable RTT responder mode.
|
|
* channel_hint - hint of the channel information where RTT responder should
|
|
* be enabled on.
|
|
* max_duration_seconds - timeout of responder mode.
|
|
* responder_info - responder information e.g. channel used for RTT responder,
|
|
* NULL if responder is not enabled.
|
|
*/
|
|
wifi_error 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)
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL || responder_info == NULL) {
|
|
ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, responder_info);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs */
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->enable_responder == NULL) {
|
|
ALOGE("%s: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = lowiWifiHalApi->enable_responder(id, iface, channel_hint,
|
|
max_duration_seconds,
|
|
responder_info);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/**
|
|
* Disable RTT responder mode.
|
|
*/
|
|
wifi_error wifi_disable_responder(wifi_request_id id,
|
|
wifi_interface_handle iface)
|
|
|
|
{
|
|
wifi_error ret;
|
|
lowi_cb_table_t *lowiWifiHalApi = NULL;
|
|
|
|
if (iface == NULL) {
|
|
ALOGE("%s: iface : %p", __FUNCTION__, iface);
|
|
return WIFI_ERROR_INVALID_ARGS;
|
|
}
|
|
|
|
/* Open LOWI dynamic library, retrieve handler to LOWI APIs */
|
|
lowiWifiHalApi = getLowiCallbackTable(
|
|
ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
|
|
if (lowiWifiHalApi == NULL ||
|
|
lowiWifiHalApi->disable_responder == NULL) {
|
|
ALOGE("%s: getLowiCallbackTable returned NULL or "
|
|
"the function pointer is NULL. Exit.", __FUNCTION__);
|
|
return WIFI_ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
ret = lowiWifiHalApi->disable_responder(id, iface);
|
|
if (ret != WIFI_SUCCESS)
|
|
ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret);
|
|
|
|
return ret;
|
|
}
|