/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <stdint.h>
#include <assert.h>
#include <string.h>
#include "syscfg/syscfg.h"
#include "os/os.h"
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
#include "ble/xcvr.h"
#include "controller/ble_ll_whitelist.h"
#include "controller/ble_ll_hci.h"
#include "controller/ble_ll_adv.h"
#include "controller/ble_ll_scan.h"
#include "controller/ble_hw.h"

#if (MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) < BLE_HW_WHITE_LIST_SIZE)
#define BLE_LL_WHITELIST_SIZE       MYNEWT_VAL(BLE_LL_WHITELIST_SIZE)
#else
#define BLE_LL_WHITELIST_SIZE       BLE_HW_WHITE_LIST_SIZE
#endif

struct ble_ll_whitelist_entry
{
    uint8_t wl_valid;
    uint8_t wl_addr_type;
    uint8_t wl_dev_addr[BLE_DEV_ADDR_LEN];
};

struct ble_ll_whitelist_entry g_ble_ll_whitelist[BLE_LL_WHITELIST_SIZE];

static int
ble_ll_whitelist_chg_allowed(void)
{
    int rc;

    /*
     * This command is not allowed if:
     *  -> advertising uses the whitelist and we are currently advertising.
     *  -> scanning uses the whitelist and is enabled.
     *  -> initiating uses whitelist and a LE create connection command is in
     *     progress
     */
    rc = 1;
    if (!ble_ll_adv_can_chg_whitelist() || !ble_ll_scan_can_chg_whitelist()) {
        rc = 0;
    }
    return rc;
}

/**
 * Clear the whitelist.
 *
 * @return int 0: success, BLE error code otherwise
 */
int
ble_ll_whitelist_clear(void)
{
    int i;
    struct ble_ll_whitelist_entry *wl;

    /* Check proper state */
    if (!ble_ll_whitelist_chg_allowed()) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    /* Set the number of entries to 0 */
    wl = &g_ble_ll_whitelist[0];
    for (i = 0; i < BLE_LL_WHITELIST_SIZE; ++i) {
        wl->wl_valid = 0;
        ++wl;
    }

#if (BLE_USES_HW_WHITELIST == 1)
    ble_hw_whitelist_clear();
#endif

    return BLE_ERR_SUCCESS;
}

/**
 * Read the size of the whitelist. This is the total number of whitelist
 * entries allowed by the controller.
 *
 * @param rspbuf Pointer to response buffer
 *
 * @return int 0: success.
 */
int
ble_ll_whitelist_read_size(uint8_t *rspbuf, uint8_t *rsplen)
{
    rspbuf[0] = BLE_LL_WHITELIST_SIZE;
    *rsplen = 1;
    return BLE_ERR_SUCCESS;
}

/**
 * Searches the whitelist to determine if the address is present in the
 * whitelist. This is an internal API that only searches the link layer
 * whitelist and does not care about the hardware whitelist
 *
 * @param addr      Device or identity address to check.
 * @param addr_type Public address (0) or random address (1)
 *
 * @return int 0: device is not on whitelist; otherwise the return value
 * is the 'position' of the device in the whitelist (the index of the element
 * plus 1).
 */
static int
ble_ll_whitelist_search(uint8_t *addr, uint8_t addr_type)
{
    int i;
    struct ble_ll_whitelist_entry *wl;

    wl = &g_ble_ll_whitelist[0];
    for (i = 0; i < BLE_LL_WHITELIST_SIZE; ++i) {
        if ((wl->wl_valid) && (wl->wl_addr_type == addr_type) &&
            (!memcmp(&wl->wl_dev_addr[0], addr, BLE_DEV_ADDR_LEN))) {
            return i + 1;
        }
        ++wl;
    }

    return 0;
}

/**
 * Is there a match between the device and a device on the whitelist.
 *
 * NOTE: This API uses the HW, if present, to determine if there was a match
 * between a received address and an address in the whitelist. If the HW does
 * not support whitelisting this API is the same as the whitelist search API
 *
 * @param addr
 * @param addr_type Public address (0) or random address (1)
 * @param is_ident  True if addr is an identity address; false otherwise
 *
 * @return int
 */
int
ble_ll_whitelist_match(uint8_t *addr, uint8_t addr_type, int is_ident)
{
    int rc;
#if (BLE_USES_HW_WHITELIST == 1)
    /*
     * XXX: This should be changed. This is HW specific: some HW may be able
     * to both resolve a private address and perform a whitelist check. The
     * current BLE hw cannot support this.
     */
    if (is_ident) {
        rc = ble_ll_whitelist_search(addr, addr_type);
    } else {
        rc = ble_hw_whitelist_match();
    }
#else
    rc = ble_ll_whitelist_search(addr, addr_type);
#endif
    return rc;
}

/**
 * Add a device to the whitelist
 *
 * @return int
 */
int
ble_ll_whitelist_add(uint8_t *addr, uint8_t addr_type)
{
    int i;
    int rc;
    struct ble_ll_whitelist_entry *wl;

    /* Must be in proper state */
    if (!ble_ll_whitelist_chg_allowed()) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    /* Check if we have any open entries */
    rc = BLE_ERR_SUCCESS;
    if (!ble_ll_whitelist_search(addr, addr_type)) {
        wl = &g_ble_ll_whitelist[0];
        for (i = 0; i < BLE_LL_WHITELIST_SIZE; ++i) {
            if (wl->wl_valid == 0) {
                memcpy(&wl->wl_dev_addr[0], addr, BLE_DEV_ADDR_LEN);
                wl->wl_addr_type = addr_type;
                wl->wl_valid = 1;
                break;
            }
            ++wl;
        }

        if (i == BLE_LL_WHITELIST_SIZE) {
            rc = BLE_ERR_MEM_CAPACITY;
        } else {
#if (BLE_USES_HW_WHITELIST == 1)
            rc = ble_hw_whitelist_add(addr, addr_type);
#endif
        }
    }

    return rc;
}

/**
 * Remove a device from the whitelist
 *
 * @param cmdbuf
 *
 * @return int 0: success, BLE error code otherwise
 */
int
ble_ll_whitelist_rmv(uint8_t *addr, uint8_t addr_type)
{
    int position;

    /* Must be in proper state */
    if (!ble_ll_whitelist_chg_allowed()) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    position = ble_ll_whitelist_search(addr, addr_type);
    if (position) {
        g_ble_ll_whitelist[position - 1].wl_valid = 0;
    }

#if (BLE_USES_HW_WHITELIST == 1)
    ble_hw_whitelist_rmv(addr, addr_type);
#endif

    return BLE_ERR_SUCCESS;
}

/**
 * Enable whitelisting.
 *
 * Note: This function has no effect if we are not using HW whitelisting
 */
void
ble_ll_whitelist_enable(void)
{
#if (BLE_USES_HW_WHITELIST == 1)
    ble_hw_whitelist_enable();
#endif
}

/**
 * Disable whitelisting.
 *
 * Note: This function has no effect if we are not using HW whitelisting
 */
void
ble_ll_whitelist_disable(void)
{
#if (BLE_USES_HW_WHITELIST == 1)
    ble_hw_whitelist_disable();
#endif
}
