/* 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.
 */

#include "sync.h"
#define LOG_TAG  "WifiHAL"
#include <utils/Log.h>
#include <time.h>
#include <errno.h>

#include "ifaceeventhandler.h"

/* Used to handle NL command events from driver/firmware. */
IfaceEventHandlerCommand *mwifiEventHandler = NULL;

/* Set the interface event monitor handler*/
wifi_error wifi_set_iface_event_handler(wifi_request_id id,
                                        wifi_interface_handle iface,
                                        wifi_event_handler eh)
{
    wifi_handle wifiHandle = getWifiHandle(iface);

    /* Check if a similar request to set iface event handler was made earlier.
     * Right now we don't differentiate between the case where (i) the new
     * Request Id is different from the current one vs (ii) both new and
     * Request Ids are the same.
     */
    if (mwifiEventHandler)
    {
        if (id == mwifiEventHandler->get_request_id()) {
            ALOGE("%s: Iface Event Handler Set for request Id %d is still"
                "running. Exit", __func__, id);
            return WIFI_ERROR_TOO_MANY_REQUESTS;
        } else {
            ALOGE("%s: Iface Event Handler Set for a different Request "
                "Id:%d is requested. Not supported. Exit", __func__, id);
            return WIFI_ERROR_NOT_SUPPORTED;
        }
    }

    mwifiEventHandler = new IfaceEventHandlerCommand(
                    wifiHandle,
                    id,
                    NL80211_CMD_REG_CHANGE);
    if (mwifiEventHandler == NULL) {
        ALOGE("%s: Error mwifiEventHandler NULL", __func__);
        return WIFI_ERROR_UNKNOWN;
    }
    mwifiEventHandler->setCallbackHandler(eh);

    return WIFI_SUCCESS;
}

/* Reset monitoring for the NL event*/
wifi_error wifi_reset_iface_event_handler(wifi_request_id id,
                                          wifi_interface_handle iface)
{
    if (mwifiEventHandler)
    {
        if (id == mwifiEventHandler->get_request_id()) {
            ALOGV("Delete Object mwifiEventHandler for id = %d", id);
            delete mwifiEventHandler;
            mwifiEventHandler = NULL;
        } else {
            ALOGE("%s: Iface Event Handler Set for a different Request "
                "Id:%d is requested. Not supported. Exit", __func__, id);
            return WIFI_ERROR_NOT_SUPPORTED;
        }
    } else {
        ALOGV("Object mwifiEventHandler for id = %d already Deleted", id);
    }

    return WIFI_SUCCESS;
}

/* This function will be the main handler for the registered incoming
 * (from driver) Commads. Calls the appropriate callback handler after
 * parsing the vendor data.
 */
int IfaceEventHandlerCommand::handleEvent(WifiEvent &event)
{
    wifiEventHandler::handleEvent(event);

    switch(mSubcmd)
    {
        case NL80211_CMD_REG_CHANGE:
        {
            char code[2];
            memset(&code[0], 0, 2);
            if(tb[NL80211_ATTR_REG_ALPHA2])
            {
                memcpy(&code[0], (char *) nla_data(tb[NL80211_ATTR_REG_ALPHA2]), 2);
            } else {
                ALOGE("%s: NL80211_ATTR_REG_ALPHA2 not found", __func__);
            }
            ALOGV("Country : %c%c", code[0], code[1]);
            if(mHandler.on_country_code_changed)
            {
                mHandler.on_country_code_changed(code);
            }
        }
        break;
        default:
            ALOGV("NL Event : %d Not supported", mSubcmd);
    }

    return NL_SKIP;
}

IfaceEventHandlerCommand::IfaceEventHandlerCommand(wifi_handle handle, int id, u32 subcmd)
        : wifiEventHandler(handle, id, subcmd)
{
    ALOGV("wifiEventHandler %p constructed", this);
    registerHandler(mSubcmd);
    memset(&mHandler, 0, sizeof(wifi_event_handler));
    mEventData = NULL;
    mDataLen = 0;
}

IfaceEventHandlerCommand::~IfaceEventHandlerCommand()
{
    ALOGV("IfaceEventHandlerCommand %p destructor", this);
    unregisterHandler(mSubcmd);
}

void IfaceEventHandlerCommand::setCallbackHandler(wifi_event_handler nHandler)
{
    mHandler = nHandler;
}

int wifiEventHandler::get_request_id()
{
    return mRequestId;
}

int IfaceEventHandlerCommand::get_request_id()
{
    return wifiEventHandler::get_request_id();
}

wifiEventHandler::wifiEventHandler(wifi_handle handle, int id, u32 subcmd)
        : WifiCommand(handle, id)
{
    mRequestId = id;
    mSubcmd = subcmd;
    registerHandler(mSubcmd);
    ALOGV("wifiEventHandler %p constructed", this);
}

wifiEventHandler::~wifiEventHandler()
{
    ALOGV("wifiEventHandler %p destructor", this);
    unregisterHandler(mSubcmd);
}

int wifiEventHandler::handleEvent(WifiEvent &event)
{
    struct genlmsghdr *gnlh = event.header();
    mSubcmd = gnlh->cmd;
    nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
            genlmsg_attrlen(gnlh, 0), NULL);
    ALOGV("Got NL Event : %d from the Driver.", gnlh->cmd);

    return NL_SKIP;
}

WifihalGeneric::WifihalGeneric(wifi_handle handle, int id, u32 vendor_id,
                                  u32 subcmd)
        : WifiVendorCommand(handle, id, vendor_id, subcmd)
{
    hal_info *info = getHalInfo(handle);

    /* Initialize the member data variables here */
    mSet = 0;
    mSetSizeMax = 0;
    mSetSizePtr = NULL;
    mConcurrencySet = 0;
    filterVersion = 0;
    filterLength = 0;
    firmware_bus_max_size = 0;
    mCapa = &(info->capa);
    mfilter_packet_read_buffer = NULL;
    mfilter_packet_length = 0;
}

WifihalGeneric::~WifihalGeneric()
{
    mCapa = NULL;
}

wifi_error WifihalGeneric::requestResponse()
{
    return WifiCommand::requestResponse(mMsg);
}

int WifihalGeneric::handleResponse(WifiEvent &reply)
{
    ALOGV("Got a Wi-Fi HAL module message from Driver");
    int i = 0;
    WifiVendorCommand::handleResponse(reply);

    // Parse the vendordata and get the attribute
    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES:
            {
                struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX,
                        (struct nlattr *)mVendorData,
                        mDataLen, NULL);

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_FEATURE_SET not found", __func__);
                    return -EINVAL;
                }
                mSet = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]);
                ALOGV("Supported feature set : %x", mSet);

                break;
            }
        case QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX:
            {
                struct nlattr *tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
                nla_parse(tb_vendor,
                    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
                    (struct nlattr *)mVendorData,mDataLen, NULL);

                if (tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE]) {
                    u32 val;
                    val = nla_get_u32(
                        tb_vendor[
                    QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE]);

                    ALOGV("%s: Num of concurrency combinations: %d",
                        __func__, val);
                    val = val > (unsigned int)mSetSizeMax ?
                          (unsigned int)mSetSizeMax : val;
                    *mSetSizePtr = val;

                    /* Extract the list of channels. */
                    if (*mSetSizePtr > 0 &&
                        tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET]) {
                        nla_memcpy(mConcurrencySet,
                            tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET],
                            sizeof(feature_set) * (*mSetSizePtr));
                    }

                    ALOGV("%s: Get concurrency matrix response received.",
                        __func__);
                    ALOGV("%s: Num of concurrency combinations : %d",
                        __func__, *mSetSizePtr);
                    ALOGV("%s: List of valid concurrency combinations is: ",
                        __func__);
                    for(i = 0; i < *mSetSizePtr; i++)
                    {
                        ALOGV("%x", *(mConcurrencySet + i));
                    }
                }
            }
            break;
        case QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER:
            {
                int subCmd;
                struct nlattr *tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX,
                        (struct nlattr *)mVendorData,
                        mDataLen, NULL);

                if (tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD])
                {
                    subCmd = nla_get_u32(
                           tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD]);
                } else {
                    /*
                     * The older drivers may not send PACKET_FILTER_SUB_CMD as
                     * they support QCA_WLAN_GET_PACKET_FILTER_SIZE only.
                     */
                    subCmd = QCA_WLAN_GET_PACKET_FILTER_SIZE;
                }
                if (subCmd == QCA_WLAN_GET_PACKET_FILTER_SIZE) {
                    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION])
                    {
                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION"
                              " not found", __FUNCTION__);
                        return -EINVAL;
                    }
                    filterVersion = nla_get_u32(
                           tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION]);
                    ALOGV("Current version : %u", filterVersion);

                    if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH])
                    {
                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH"
                              " not found", __FUNCTION__);
                        return -EINVAL;
                    }
                    filterLength = nla_get_u32(
                        tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_TOTAL_LENGTH]);
                    ALOGV("Max filter length Supported : %u", filterLength);
                } else if (subCmd == QCA_WLAN_READ_PACKET_FILTER) {

                   if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])
                   {
                       ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM"
                             " not found", __FUNCTION__);
                       return -EINVAL;
                   }
                   if (nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])
                           < mfilter_packet_length)
                   {
                       ALOGE("%s: Expected packet filter length :%d but received only: %d bytes",
                             __FUNCTION__, mfilter_packet_length,
                             nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]));
                       return -EINVAL;
                   }
                   memcpy(mfilter_packet_read_buffer,
                      nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]),
                      mfilter_packet_length);
                   ALOGV("Filter Program length : %u", mfilter_packet_length);
                } else {
                       ALOGE("%s: Unknown APF sub command received",
                             __FUNCTION__);
                       return -EINVAL;
                }

            }
            break;
        case QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE:
            {
                struct nlattr *tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX,
                          (struct nlattr *)mVendorData, mDataLen, NULL);

                if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE])
                {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE"
                          " not found", __FUNCTION__);
                    return -EINVAL;
                }
                firmware_bus_max_size = nla_get_u32(
                       tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE]);
                ALOGV("Max BUS size Supported: %d", firmware_bus_max_size);
            }
            break;
        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES:
            {
                struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
                nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
                          (struct nlattr *)mVendorData,mDataLen, NULL);

                if (wifiParseCapabilities(tbVendor) == WIFI_SUCCESS) {
                    ALOGV("%s: GSCAN Capabilities:\n"
                          "     max_ap_cache_per_scan:%d\n"
                          "     max_bssid_history_entries:%d\n"
                          "     max_hotlist_bssids:%d\n"
                          "     max_hotlist_ssids:%d\n"
                          "     max_rssi_sample_size:%d\n"
                          "     max_scan_buckets:%d\n"
                          "     max_scan_cache_size:%d\n"
                          "     max_scan_reporting_threshold:%d\n"
                          "     max_significant_wifi_change_aps:%d\n"
                          "     max_number_epno_networks:%d\n"
                          "     max_number_epno_networks_by_ssid:%d\n"
                          "     max_number_of_white_listed_ssid:%d.",
                          __FUNCTION__, mCapa->gscan_capa.max_ap_cache_per_scan,
                          mCapa->gscan_capa.max_bssid_history_entries,
                          mCapa->gscan_capa.max_hotlist_bssids,
                          mCapa->gscan_capa.max_hotlist_ssids,
                          mCapa->gscan_capa.max_rssi_sample_size,
                          mCapa->gscan_capa.max_scan_buckets,
                          mCapa->gscan_capa.max_scan_cache_size,
                          mCapa->gscan_capa.max_scan_reporting_threshold,
                          mCapa->gscan_capa.max_significant_wifi_change_aps,
                          mCapa->gscan_capa.max_number_epno_networks,
                          mCapa->gscan_capa.max_number_epno_networks_by_ssid,
                          mCapa->gscan_capa.max_number_of_white_listed_ssid);

                    ALOGV("%s: Roaming Capabilities:\n"
                          "    max_blacklist_size: %d\n"
                          "    max_whitelist_size: %d\n",
                          __FUNCTION__, mCapa->roaming_capa.max_blacklist_size,
                          mCapa->roaming_capa.max_whitelist_size);
                }
            }
            break;
        default :
            ALOGE("%s: Wrong Wi-Fi HAL event received %d", __func__, mSubcmd);
    }
    return NL_SKIP;
}

/* Parses and extract capabilities results. */
wifi_error WifihalGeneric::wifiParseCapabilities(struct nlattr **tbVendor)
{
    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE not found",
              __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_scan_cache_size = nla_get_u32(tbVendor[
                              QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS not found",
              __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_scan_buckets = nla_get_u32(tbVendor[
                                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN not found",
              __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_ap_cache_per_scan = nla_get_u32(tbVendor[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE not found",
              __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_rssi_sample_size = nla_get_u32(tbVendor[
                             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD not"
              " found", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_scan_reporting_threshold = nla_get_u32(tbVendor[
                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS not found",
              __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_hotlist_bssids = nla_get_u32(tbVendor[
                               QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]
       ) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS "
              "not found", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_significant_wifi_change_aps = nla_get_u32(tbVendor[
                  QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES not "
              "found", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    mCapa->gscan_capa.max_bssid_history_entries = nla_get_u32(tbVendor[
                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES]);

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS not found. Set"
              " to 0.", __FUNCTION__);
        mCapa->gscan_capa.max_hotlist_ssids = 0;
    } else {
        mCapa->gscan_capa.max_hotlist_ssids = nla_get_u32(tbVendor[
                                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS]);
    }

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS not found. Set"
              " to 0.", __FUNCTION__);
        mCapa->gscan_capa.max_number_epno_networks = 0;
    } else {
        mCapa->gscan_capa.max_number_epno_networks
            = nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS
                                  ]);
    }

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID not "
              "found. Set to 0.", __FUNCTION__);
        mCapa->gscan_capa.max_number_epno_networks_by_ssid = 0;
    } else {
        mCapa->gscan_capa.max_number_epno_networks_by_ssid = nla_get_u32(tbVendor[
                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID]);
    }

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID not "
              "found. Set to 0.", __FUNCTION__);
        mCapa->gscan_capa.max_number_of_white_listed_ssid = 0;
        mCapa->roaming_capa.max_whitelist_size = 0;
    } else {
        mCapa->gscan_capa.max_number_of_white_listed_ssid = nla_get_u32(tbVendor[
                         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID]);
        mCapa->roaming_capa.max_whitelist_size = mCapa->gscan_capa.max_number_of_white_listed_ssid;
    }

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_CAPABILITIES_MAX_NUM_BLACKLISTED_BSSID]) {
        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
            "_NUM_BLACKLIST_BSSID not found. Set to 0.", __FUNCTION__);
        mCapa->roaming_capa.max_blacklist_size = 0;
    } else {
        mCapa->roaming_capa.max_blacklist_size = nla_get_u32(tbVendor[
                                      QCA_WLAN_VENDOR_ATTR_CAPABILITIES_MAX_NUM_BLACKLISTED_BSSID]);
    }
    return WIFI_SUCCESS;
}

void WifihalGeneric::getResponseparams(feature_set *pset)
{
    *pset = mSet;
}

void WifihalGeneric::setMaxSetSize(int set_size_max) {
    mSetSizeMax = set_size_max;
}

void WifihalGeneric::setConcurrencySet(feature_set set[]) {
    mConcurrencySet = set;
}

void WifihalGeneric::setSizePtr(int *set_size) {
    mSetSizePtr = set_size;
}

int WifihalGeneric::getFilterVersion() {
    return filterVersion;
}

int WifihalGeneric::getFilterLength() {
    return filterLength;
}
void WifihalGeneric::setPacketBufferParams(u8 *host_packet_buffer, int packet_length) {
    mfilter_packet_read_buffer = host_packet_buffer;
    mfilter_packet_length = packet_length;
}

int WifihalGeneric::getBusSize() {
    return firmware_bus_max_size;
}

wifi_error WifihalGeneric::wifiGetCapabilities(wifi_interface_handle handle)
{
    wifi_error ret;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(handle);

    /* Create the NL message. */
    ret = create();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Failed to create NL message,  Error:%d", __FUNCTION__, ret);
        return ret;
    }

    /* Set the interface Id of the message. */
    ret = set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Failed to set interface Id of message, Error:%d", __FUNCTION__, ret);
        return ret;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlData = attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData)
        return WIFI_ERROR_OUT_OF_MEMORY;

    ret = put_u32(QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, mId);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Failed to add request_ID to NL command, Error:%d", __FUNCTION__, ret);
        return ret;
    }

    attr_end(nlData);

    ret = requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret);

    return ret;
}
