/*
 * Copyright (c) 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 "android.hardware.nfc@1.1-impl"

#include "NfcApiGet.h"
#include <log/log.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <cstring>
#include <dlfcn.h>

struct nqx_devinfo {
    // Must be kept in sync with nqx_ UAPI
    unsigned char chip_type;
    unsigned char rom_version;
    unsigned char fw_major;
    unsigned char fw_minor;
};

union nqx_uinfo {
    unsigned int i;
    struct nqx_devinfo info;
};

bool nfc_debug_enabled = false;
static hal_api_struct_t *hal_api_s = nullptr;
static bool struct_initialized = false;
static void* hal_handle = nullptr;

/******************************************************************************
 * Function         chipInfo
 *
 * Description      This function returns a success/fail integer, and populates
 *                  nqx_info with chip information.
 *
 * Returns          int return status (0/-1).
 *
 ******************************************************************************/
static int chipInfo(union nqx_uinfo* nqx_info) {
    int fp;

    fp = open(DEV_NODE, O_RDONLY);
    if (fp < 0) {
        ALOGE("Not able to open dev node %s due to errno (%d) %s", DEV_NODE, errno, strerror(errno));
        return STATUS_FAILURE;
    }

    nqx_info->i = ioctl(fp, NFCC_GET_INFO, 0);
    int retval = static_cast<int> (nqx_info->i);
    if (retval < 0) {
        ALOGE("Failed to retrieve chip ID from hardware due to errno (%d), %s", errno, strerror(errno));
        return STATUS_FAILURE;
    }

    ALOGD("NFC chip id = 0x%x\n", nqx_info->info.chip_type);
    ALOGD("NFC FW Ver = %02x.%02x.%02x\n", nqx_info->info.rom_version, nqx_info->info.fw_major, nqx_info->info.fw_minor);

    close(fp);
    return STATUS_SUCCESS;
}

/******************************************************************************
 * Function         getHalFileName
 *
 * Description      This function determines which library should be opened,
 *                  based on the NFC chip ID from chipInfo().
 *
 * Returns          char const* file_name
 *
 ******************************************************************************/
static char const* getHalFileName() {
    // get chip info from hardware, and return the correct HAL file name.
    union nqx_uinfo nqx_info;
    int ret = chipInfo(&nqx_info);

    if (ret == 0) {

        switch(nqx_info.info.chip_type) {

            case PN553_ID_A0:
            case NQ310_ID: // ALSO PN553 B0
            case NQ210_ID:
            case NQ440_ID: // ALSO NQ330
            case NQ220_ID:
                ALOGD("NFC HW chip-id matches with NQxxx");
                return NQX_FILE_NAME;

            case SN100X_ID_A:
            case SN100X_ID_B:
                // SN100 has chip id 0xa4 or 0xa3
                ALOGD("NFC HW chip-id matches with SN100X");
                return SN100X_FILE_NAME;

            default:
                // if chip id isn't matched, load the NQxxx HAL.
                ALOGD("Chip does not match known ID - defaulting to NQX library.");
                return NQX_FILE_NAME;
        }
    }

    else {
        ALOGD("Obtaining Chip ID failed, attempting loading of default shared library instead.");
        return NQX_FILE_NAME;
    }
}

/******************************************************************************
 * Function         unloadHalApiStruct
 *
 * Description      This function is responsible for closing the dynamic library
 *                  and unloading the HAL struct; in order to save memory on low
 *                  memory targets.
 *
 * Returns          void.
 *
 ******************************************************************************/
void unloadHalApiStruct() {
    hal_api_s = nullptr;
    struct_initialized = false;
    dlclose(hal_handle);
    ALOGD("Unloaded HAL API Struct");
}

/******************************************************************************
 * Function        getHalApiStruct
 *
 * Description      This function initializes a struct of pointers to functions
 *                  within the NFC HAL implementation.
 *
 * Returns          hal_api_s pointer or nullptr.
 *
 ******************************************************************************/
hal_api_struct_t* getHalApiStruct() {

    char const* linkerror = nullptr;
    char const* file_name = nullptr;

    /*
     * If our HAL has been loaded successfully, we don't want to re-open it on every NFC function call.
     * Conversely, if loading the HAL failed, we want to ensure we're not repeatedly trying to link.
     */
    if (struct_initialized) {
        return hal_api_s;
    }

    // Obtain the file name for the HAL library we wish to load
    file_name = getHalFileName();
    // Reset any errors
    dlerror();

    /*
     * Attempt to load the library!
     * /vendor/lib(64)/hw/nci_nfc.nqx.default.hw.so for NQx
     * /vendor/lib(64)/hw/nci_nfc.sn100x.default.hw.so otherwise
     */
    hal_handle = dlopen(file_name, RTLD_NOW);
    linkerror = dlerror();
    if (linkerror != nullptr) {
        ALOGE("Error opening HAL file: %s with linking error: %s", file_name, linkerror);
        /*
         * Set struct as initialized even if loading fails, so that loading is only attempted
         * once per NFC service initialization attempt.
         */
        struct_initialized = true;
        return nullptr;
    }

    ALOGD("Loading nfc HAL function table");
    // Reset errors again
    dlerror();
    hal_api_s = (hal_api_struct_t*)dlsym(hal_handle, "api_funcs");
    linkerror = dlerror();
    if (linkerror != nullptr) {
        ALOGE("Error loading HAL function API symbol table: %s", linkerror);
        struct_initialized = true;
        return nullptr;
    }

    //set the debug status and set the active status of the HIDL.
    nfc_debug_enabled = hal_api_s->phNxpNciHal_get_debug_status();
    struct_initialized = true;
    return hal_api_s;
}
