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