/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <linux/pkt_sched.h>
#include <linux-private/linux/fib_rules.h>
#include <netlink/object-api.h>
#include <netlink-private/object-api.h>
#include <netlink-private/types.h>
#include <dlfcn.h>
#include <pthread.h>
#include "wifi_hal.h"
#include "common.h"
#include <errno.h>

interface_info *getIfaceInfo(wifi_interface_handle handle)
{
    return (interface_info *)handle;
}

wifi_handle getWifiHandle(wifi_interface_handle handle)
{
    return getIfaceInfo(handle)->handle;
}

hal_info *getHalInfo(wifi_handle handle)
{
    return (hal_info *)handle;
}

hal_info *getHalInfo(wifi_interface_handle handle)
{
    return getHalInfo(getWifiHandle(handle));
}

wifi_handle getWifiHandle(hal_info *info)
{
    return (wifi_handle)info;
}

wifi_interface_handle getIfaceHandle(interface_info *info)
{
    return (wifi_interface_handle)info;
}

wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
{
    hal_info *info = (hal_info *)handle;

    pthread_mutex_lock(&info->cb_lock);

    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;

    for (int i = 0; i < info->num_event_cb; i++) {
        if(info->event_cb[i].nl_cmd == cmd &&
           info->event_cb[i].cb_arg == arg) {
            info->event_cb[i].cb_func = func;
            ALOGV("Updated event handler %p for nl_cmd 0x%0x"
                    " and arg %p", func, cmd, arg);
            pthread_mutex_unlock(&info->cb_lock);
            return WIFI_SUCCESS;
        }
    }

    if (info->num_event_cb < info->alloc_event_cb) {
        info->event_cb[info->num_event_cb].nl_cmd  = cmd;
        info->event_cb[info->num_event_cb].vendor_id  = 0;
        info->event_cb[info->num_event_cb].vendor_subcmd  = 0;
        info->event_cb[info->num_event_cb].cb_func = func;
        info->event_cb[info->num_event_cb].cb_arg  = arg;
        info->num_event_cb++;
        ALOGV("Successfully added event handler %p for command %d", func, cmd);
        result = WIFI_SUCCESS;
    } else {
        result = WIFI_ERROR_OUT_OF_MEMORY;
    }

    pthread_mutex_unlock(&info->cb_lock);
    return result;
}

wifi_error wifi_register_vendor_handler(wifi_handle handle,
        uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
{
    hal_info *info = (hal_info *)handle;

    pthread_mutex_lock(&info->cb_lock);

    wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;

    for (int i = 0; i < info->num_event_cb; i++) {
        if(info->event_cb[i].vendor_id  == id &&
           info->event_cb[i].vendor_subcmd == subcmd)
        {
            info->event_cb[i].cb_func = func;
            info->event_cb[i].cb_arg  = arg;
            ALOGV("Updated event handler %p for vendor 0x%0x, subcmd 0x%0x"
                " and arg %p", func, id, subcmd, arg);
            pthread_mutex_unlock(&info->cb_lock);
            return WIFI_SUCCESS;
        }
    }

    if (info->num_event_cb < info->alloc_event_cb) {
        info->event_cb[info->num_event_cb].nl_cmd  = NL80211_CMD_VENDOR;
        info->event_cb[info->num_event_cb].vendor_id  = id;
        info->event_cb[info->num_event_cb].vendor_subcmd  = subcmd;
        info->event_cb[info->num_event_cb].cb_func = func;
        info->event_cb[info->num_event_cb].cb_arg  = arg;
        info->num_event_cb++;
        ALOGV("Added event handler %p for vendor 0x%0x, subcmd 0x%0x and arg"
            " %p", func, id, subcmd, arg);
        result = WIFI_SUCCESS;
    } else {
        result = WIFI_ERROR_OUT_OF_MEMORY;
    }

    pthread_mutex_unlock(&info->cb_lock);
    return result;
}

void wifi_unregister_handler(wifi_handle handle, int cmd)
{
    hal_info *info = (hal_info *)handle;

    if (cmd == NL80211_CMD_VENDOR) {
        ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
        return;
    }

    pthread_mutex_lock(&info->cb_lock);

    for (int i = 0; i < info->num_event_cb; i++) {
        if (info->event_cb[i].nl_cmd == cmd) {
            if(i < info->num_event_cb-1) {
                /* No need to memmove if only one entry exist and deleting
                 * the same, as the num_event_cb will become 0 in this case.
                 */
                memmove(&info->event_cb[i], &info->event_cb[i+1],
                        (info->num_event_cb - i) * sizeof(cb_info));
            }
            info->num_event_cb--;
            ALOGV("Successfully removed event handler for command %d", cmd);
            break;
        }
    }

    pthread_mutex_unlock(&info->cb_lock);
}

void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
{
    hal_info *info = (hal_info *)handle;

    pthread_mutex_lock(&info->cb_lock);

    for (int i = 0; i < info->num_event_cb; i++) {

        if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
                && info->event_cb[i].vendor_id == id
                && info->event_cb[i].vendor_subcmd == subcmd) {
            if(i < info->num_event_cb-1) {
                /* No need to memmove if only one entry exist and deleting
                 * the same, as the num_event_cb will become 0 in this case.
                 */
                memmove(&info->event_cb[i], &info->event_cb[i+1],
                        (info->num_event_cb - i) * sizeof(cb_info));
            }
            info->num_event_cb--;
            ALOGV("Successfully removed event handler for vendor 0x%0x", id);
            break;
        }
    }

    pthread_mutex_unlock(&info->cb_lock);
}


#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

void hexdump(void *buf, u16 len)
{
    int i=0;
    char *bytes = (char *)buf;

    if (len) {
        ALOGV("******HexDump len:%d*********", len);
        for (i = 0; ((i + 7) < len); i+=8) {
            ALOGV("%02x %02x %02x %02x   %02x %02x %02x %02x",
                bytes[i], bytes[i+1],
                bytes[i+2], bytes[i+3],
                bytes[i+4], bytes[i+5],
                bytes[i+6], bytes[i+7]);
        }
        if ((len - i) >= 4) {
            ALOGV("%02x %02x %02x %02x",
                bytes[i], bytes[i+1],
                bytes[i+2], bytes[i+3]);
            i+=4;
        }
        for (;i < len;i++) {
            ALOGV("%02x", bytes[i]);
        }
        ALOGV("******HexDump End***********");
    } else {
        return;
    }
}

/* Firmware sends RSSI value without noise floor.
 * Add noise floor to the same and return absolute values.
 */
u8 get_rssi(u8 rssi_wo_noise_floor)
{
    return abs((int)rssi_wo_noise_floor - 96);
}

#ifdef __cplusplus
}
#endif /* __cplusplus */

/* Pointer to the table of LOWI callback funcs */
lowi_cb_table_t *LowiWifiHalApi = NULL;
/* LowiSupportedCapabilities read */
u32 lowiSupportedCapabilities = 0;

int compareLowiVersion(u16 major, u16 minor, u16 micro)
{
    u32 currVersion = 0x10000*(WIFIHAL_LOWI_MAJOR_VERSION) + \
                      0x100*(WIFIHAL_LOWI_MINOR_VERSION) + \
                      WIFIHAL_LOWI_MICRO_VERSION;

    u32 lowiVersion = 0x10000*(major) + \
                      0x100*(minor) + \
                      micro;

    return (memcmp(&currVersion, &lowiVersion, sizeof(u32)));
}

/*
 * This function will open the lowi shared library and obtain the
 * Lowi Callback table and the capabilities supported.
 * A version check is also performed in this function and if the version
 * check fails then the callback table returned will be NULL.
 */
wifi_error fetchLowiCbTableAndCapabilities(lowi_cb_table_t **lowi_wifihal_api,
                                           bool *lowi_get_capa_supported)
{
    getCbTable_t* lowiCbTable = NULL;
    int ret = 0;
    wifi_error retVal = WIFI_SUCCESS;

    *lowi_wifihal_api = NULL;
    *lowi_get_capa_supported = false;

#if __WORDSIZE == 64
    void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW);
#else
    void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW);
#endif
    if (!lowi_handle) {
        ALOGE("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror());
        return WIFI_ERROR_UNKNOWN;
    }

    lowiCbTable = (getCbTable_t*)dlsym(lowi_handle,
                                       "lowi_wifihal_get_cb_table");
    if (!lowiCbTable) {
        ALOGE("%s: NULL lowi callback table", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    *lowi_wifihal_api = lowiCbTable();

    /* First check whether lowi module implements the get_lowi_version
     * function. All the functions in lowi module starts with
     * "lowi_wifihal_" prefix thus the below function name.
     */
    if ((dlsym(lowi_handle, "lowi_wifihal_get_lowi_version") != NULL) &&
        ((*lowi_wifihal_api)->get_lowi_version != NULL)) {
        u16 lowiMajorVersion = WIFIHAL_LOWI_MAJOR_VERSION;
        u16 lowiMinorVersion = WIFIHAL_LOWI_MINOR_VERSION;
        u16 lowiMicroVersion = WIFIHAL_LOWI_MICRO_VERSION;
        int versionCheck = -1;

        ret = (*lowi_wifihal_api)->get_lowi_version(&lowiMajorVersion,
                                                    &lowiMinorVersion,
                                                    &lowiMicroVersion);
        if (ret) {
            ALOGE("%s: get_lowi_version returned error:%d",
                  __FUNCTION__, ret);
            retVal = WIFI_ERROR_NOT_SUPPORTED;
            goto cleanup;
        }
        ALOGV("%s: Lowi version:%d.%d.%d", __FUNCTION__,
              lowiMajorVersion, lowiMinorVersion,
              lowiMicroVersion);

        /* Compare the version with version in wifihal_internal.h */
        versionCheck = compareLowiVersion(lowiMajorVersion,
                                          lowiMinorVersion,
                                          lowiMicroVersion);
        if (versionCheck < 0) {
            ALOGE("%s: Version Check failed:%d", __FUNCTION__,
                  versionCheck);
            retVal = WIFI_ERROR_NOT_SUPPORTED;
            goto cleanup;
        }
    }
    else {
        ALOGV("%s: lowi_wifihal_get_lowi_version not present",
              __FUNCTION__);
    }


    /* Check if get_lowi_capabilities func pointer exists in
     * the lowi lib and populate lowi_get_capa_supported
     * All the functions in lowi modules starts with
     * "lowi_wifihal_ prefix" thus the below function name.
     */
    if (dlsym(lowi_handle, "lowi_wifihal_get_lowi_capabilities") != NULL) {
        *lowi_get_capa_supported = true;
    }
    else {
        ALOGV("lowi_wifihal_get_lowi_capabilities() is not supported.");
        *lowi_get_capa_supported = false;
    }
cleanup:
    if (retVal) {
        *lowi_wifihal_api = NULL;
    }
    return retVal;
}

lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities)
{
    int ret = WIFI_SUCCESS;
    bool lowi_get_capabilities_support = false;

    if (LowiWifiHalApi == NULL) {
        ALOGV("%s: LowiWifiHalApi Null, Initialize Lowi",
              __FUNCTION__);
        ret = fetchLowiCbTableAndCapabilities(&LowiWifiHalApi,
                                              &lowi_get_capabilities_support);
        if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL ||
            LowiWifiHalApi->init == NULL) {
            ALOGE("%s: LOWI is not supported.", __FUNCTION__);
            goto cleanup;
        }
        /* Initialize LOWI if it isn't up already. */
        ret = LowiWifiHalApi->init();
        if (ret) {
            ALOGE("%s: failed lowi initialization. "
                "Returned error:%d. Exit.", __FUNCTION__, ret);
            goto cleanup;
        }
        if (!lowi_get_capabilities_support ||
            LowiWifiHalApi->get_lowi_capabilities == NULL) {
                ALOGV("%s: Allow rtt APIs thru LOWI to proceed even though "
                      "get_lowi_capabilities() is not supported. Returning",
                      __FUNCTION__);
                lowiSupportedCapabilities |=
                    (ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED);
                return LowiWifiHalApi;
        }
        ret =
            LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities);
        if (ret) {
            ALOGV("%s: failed to get lowi supported capabilities."
                "Returned error:%d. Exit.", __FUNCTION__, ret);
            goto cleanup;
        }
    } else if (lowiSupportedCapabilities == 0 &&
               LowiWifiHalApi->get_lowi_capabilities) {
            LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities);
    }

    if ((lowiSupportedCapabilities & requested_lowi_capabilities) == 0) {
        return NULL;
    }
    return LowiWifiHalApi;

cleanup:
    if (LowiWifiHalApi && LowiWifiHalApi->destroy) {
        ret = LowiWifiHalApi->destroy();
    }
    LowiWifiHalApi = NULL;
    lowiSupportedCapabilities = 0;
    return LowiWifiHalApi;
}

wifi_error mapKernelErrortoWifiHalError(int kern_err)
{
    if (kern_err >= 0)
        return WIFI_SUCCESS;

    switch (kern_err) {
        case -EOPNOTSUPP:
            return WIFI_ERROR_NOT_SUPPORTED;
        case -EAGAIN:
            return WIFI_ERROR_NOT_AVAILABLE;
        case -EINVAL:
            return WIFI_ERROR_INVALID_ARGS;
        case -ETIMEDOUT:
            return WIFI_ERROR_TIMED_OUT;
        case -ENOMEM:
            return WIFI_ERROR_OUT_OF_MEMORY;
        case -EBUSY:
            return WIFI_ERROR_BUSY;
        case -ENOBUFS:
            return WIFI_ERROR_TOO_MANY_REQUESTS;
    }
    return WIFI_ERROR_UNKNOWN;
}
