/* 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.
 *
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
 * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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"
#include "common.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);
    memset(tb, 0, sizeof(struct nlattr *) * (NL80211_ATTR_MAX + 1));
    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;
    res_size = 0;
    channel_buff = NULL;
    mRadio_matrix = NULL;
    mRadio_matrix_max_size = 0;
    mRadio_matrix_size = NULL;
    memset(&mDriverFeatures, 0, sizeof(mDriverFeatures));
    memset(&mRadarResultParams, 0, sizeof(RadarHistoryResultsParams));
}

WifihalGeneric::~WifihalGeneric()
{
    mCapa = NULL;
    if (mDriverFeatures.flags != NULL) {
        free(mDriverFeatures.flags);
        mDriverFeatures.flags = NULL;
    }
}

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

static u32 get_wifi_iftype_masks(u32 in_mask)
{
    u32 op_mask = 0;

    if (in_mask & BIT(NL80211_IFTYPE_STATION)) {
        op_mask |= BIT(WIFI_INTERFACE_STA);
        op_mask |= BIT(WIFI_INTERFACE_TDLS);
    }
    if (in_mask & BIT(NL80211_IFTYPE_AP))
        op_mask |= BIT(WIFI_INTERFACE_SOFTAP);
    if (in_mask & BIT(NL80211_IFTYPE_P2P_CLIENT))
        op_mask |= BIT(WIFI_INTERFACE_P2P_CLIENT);
    if (in_mask & BIT(NL80211_IFTYPE_P2P_GO))
        op_mask |= BIT(WIFI_INTERFACE_P2P_GO);
    if (in_mask & BIT(NL80211_IFTYPE_NAN))
        op_mask |= BIT(WIFI_INTERFACE_NAN);

    return op_mask;
}

static wifi_channel_width get_channel_width(u32 nl_width)
{
    switch(nl_width) {
    case NL80211_CHAN_WIDTH_20:
         return WIFI_CHAN_WIDTH_20;
    case NL80211_CHAN_WIDTH_40:
         return WIFI_CHAN_WIDTH_40;
    case NL80211_CHAN_WIDTH_80:
         return WIFI_CHAN_WIDTH_80;
    case NL80211_CHAN_WIDTH_160:
         return WIFI_CHAN_WIDTH_160;
    case NL80211_CHAN_WIDTH_80P80:
         return WIFI_CHAN_WIDTH_80P80;
    case NL80211_CHAN_WIDTH_5:
         return WIFI_CHAN_WIDTH_5;
    case NL80211_CHAN_WIDTH_10:
         return WIFI_CHAN_WIDTH_10;
    default:
         return WIFI_CHAN_WIDTH_INVALID;
    }
}

int WifihalGeneric::handle_response_usable_channels(struct nlattr *VendorData,
                                                    u32 mDataLen)
{
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1];
    struct nlattr *curr_attr;
    wifi_usable_channel *chan_info = NULL;
    int rem;
    u32 currSize = 0;

    if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX,
                  (struct nlattr *)mVendorData, mDataLen, NULL)) {
         ALOGE("Failed to parse NL channels list");
         return WIFI_ERROR_INVALID_ARGS;
    }

    if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO]) {
         ALOGE("%s: USABLE_CHANNELS_CHAN_INFO not found", __FUNCTION__);
         return WIFI_ERROR_INVALID_ARGS;
    }

    for_each_nested_attribute(curr_attr,
                     tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO], rem) {
         struct nlattr *ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX + 1];

         if (currSize >= mSetSizeMax) {
              ALOGE("Got max channels %d completed", mSetSizeMax);
              break;
         }

         if (nla_parse_nested(ch_info, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX,
                              curr_attr, NULL)) {
              ALOGE("Failed to get usable channel info");
              return NL_SKIP;
         }

         chan_info = &channel_buff[currSize];
         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]) {
              ALOGE("%s: CHAN_INFO_PRIMARY_FREQ not found",
                    __FUNCTION__);
              return NL_SKIP;
         }

         chan_info->freq = nla_get_u32(ch_info[
                                  QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]);
         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]) {
              ALOGE("%s: CHAN_INFO_BANDWIDTH not found",
                    __FUNCTION__);
              return NL_SKIP;
         }

         chan_info->width = get_channel_width(nla_get_u32(
                            ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]));
         if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]) {
              ALOGE("%s: CHAN_INFO_IFACE_MODE_MASK not found",
                    __FUNCTION__);
              return NL_SKIP;
         }

         chan_info->iface_mode_mask = get_wifi_iftype_masks(nla_get_u32(
                      ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]));
         ALOGV("Primary freq %d BW %d iface mask %d", chan_info->freq,
               chan_info->width, chan_info->iface_mode_mask);
         currSize++;
    }

    res_size = currSize;
    ALOGV("%s: Result size %d", __FUNCTION__, res_size);

    return NL_SKIP;
}

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 : %" PRIx64, mSet);

                break;
            }
        case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
            {
                struct nlattr *attr;
                struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
                          (struct nlattr *)mVendorData, mDataLen, NULL);
                attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
                if (attr) {
                    int len = nla_len(attr);
                    mDriverFeatures.flags = (u8 *)malloc(len);
                    if (mDriverFeatures.flags != NULL) {
                        memcpy(mDriverFeatures.flags, nla_data(attr), len);
                        mDriverFeatures.flags_len = len;
                    }
                 }
                 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("%" PRIx64, *(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 only.
                     */
                    subCmd = QCA_WLAN_GET_PACKET_FILTER;
                }
                if (subCmd == QCA_WLAN_GET_PACKET_FILTER) {
                    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_SIZE])
                    {
                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE"
                              " not found", __FUNCTION__);
                        return -EINVAL;
                    }
                    filterLength = nla_get_u32(
                        tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE]);
                    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;
        case QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS:
            return handle_response_usable_channels((struct nlattr *)mVendorData,
                                                   mDataLen);
        case QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY:
            {
                wifiParseRadarHistory();
            }
            break;
        case QCA_NL80211_VENDOR_SUBCMD_GET_RADIO_COMBINATION_MATRIX:
            {
                wifi_parse_radio_combinations_matrix();
            }
	    break;
        case QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY:
            {
                struct nlattr *tb_vendor[
                        QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX + 1];
                nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_MAX,
                          (struct nlattr *)mVendorData,mDataLen, NULL);

                if(tb_vendor[QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION])
                {
                    mInfo->sar_version = (qca_wlan_vendor_sar_version) nla_get_u32(tb_vendor[
                                               QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION]);
                }
                ALOGV("%s: sar_version return %d", __func__, mInfo->sar_version);
            }
            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_GSCAN_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_GSCAN_MAX_NUM_BLACKLISTED_BSSID]);
    }
    return WIFI_SUCCESS;
}

wifi_error WifihalGeneric::wifi_parse_radio_combinations_matrix() {
    // tbVendor
    struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_MAX + 1];
    int rem = 0, rem_radio = 0;
    u32 num_radio_combinations = 0, num_radio_configurations = 0;
    // nested radio matrix configurations
    struct nlattr *radio_combination[QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX + 1];
    struct nlattr *attr, *attr_cfg;
    struct nlattr *radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX + 1];
    u8 band, antenna;
    u32 result_size = sizeof(u32); /* num_radio_combinations */
    bool max_size_exceeded = false;
    u32 size_needed = 0, radio_cfg_size = 0;
    bool invalid_radio_cfg = false;
    wifi_radio_combination *radio_combination_ptr;
    wifi_radio_configuration *radio_config;
    u8 *buff_ptr;

    static struct nla_policy
        radio_combination_policy[QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX + 1] = {
            [QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_CFGS] = { .type = NLA_NESTED },
        };

    static struct nla_policy
        radio_cfg_policy[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX + 1] = {
            [QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND] = { .type = NLA_U32 },
            [QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA] = { .type = NLA_U8 },
        };

    if (nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_MAX,
                (struct nlattr *)mVendorData,mDataLen, NULL)) {
        ALOGE("%s: nla_parse ATTR_RADIO_MATRIX fail", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_SUPPORTED_CFGS]) {
        ALOGE("%s: radio matrix attr entries not present", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    if (!mRadio_matrix) {
        ALOGE("%s: radio matrix buffer is null", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    buff_ptr = (u8 *)mRadio_matrix;
    buff_ptr += sizeof(u32); /* num_radio_combinations */
    nla_for_each_nested(attr,
            tbVendor[QCA_WLAN_VENDOR_ATTR_RADIO_MATRIX_SUPPORTED_CFGS],
            rem) {
        if (nla_parse_nested(radio_combination,
                    QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_MAX,
                    attr, radio_combination_policy)) {
            ALOGI("%s: nla_parse_nested radio combination fail", __FUNCTION__);
            continue;
        }
        radio_combination_ptr = (wifi_radio_combination *)buff_ptr;

        num_radio_configurations = 0;
        radio_cfg_size = 0;
        nla_for_each_nested(attr_cfg,
                radio_combination[QCA_WLAN_VENDOR_ATTR_RADIO_COMBINATIONS_CFGS],
                rem_radio) {
            if (nla_parse_nested(radio_cfg,
                        QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_MAX,
                        attr_cfg, radio_cfg_policy)) {
                ALOGI("%s: nla_parse_nested radio cfg attr fail", __FUNCTION__);
                continue;
            }

            if (!radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND] ||
                !radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA]) {
                ALOGI("%s: band/antenna info not present", __FUNCTION__);
                continue;
            }

            if (!invalid_radio_cfg) {
                if (!num_radio_configurations) {
                    size_needed = sizeof(wifi_radio_configuration) +
                                  sizeof(u32);
                    buff_ptr += sizeof(u32); /* num_radio_configurations */
                } else {
                    size_needed = sizeof(wifi_radio_configuration);
                    buff_ptr += sizeof(wifi_radio_configuration);
                }
            }
            if (mRadio_matrix_max_size < result_size + size_needed) {
                ALOGI("%s: Max size reached, max size %u, needed %u",
                        __FUNCTION__, mRadio_matrix_max_size,
                        result_size + size_needed);
                max_size_exceeded = true;
                break;
            }
            invalid_radio_cfg = false;
            radio_config = (wifi_radio_configuration *)buff_ptr;

            if (radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND]) {
                band = nla_get_u32(
                        radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_BAND]);
                if (band == QCA_SETBAND_5G) {
                    radio_config->band = WLAN_MAC_5_0_BAND;
                } else if (band == QCA_SETBAND_6G) {
                    radio_config->band = WLAN_MAC_6_0_BAND;
                } else if (band == QCA_SETBAND_2G) {
                    radio_config->band = WLAN_MAC_2_4_BAND;
                } else {
                    ALOGI("%s: Invalid band value %d", __FUNCTION__, band);
                    invalid_radio_cfg = true;
                    continue;
                }
            }
            if (radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA]) {
                antenna = nla_get_u8(
                        radio_cfg[QCA_WLAN_VENDOR_ATTR_SUPPORTED_RADIO_CFG_ANTENNA]);
                if (antenna == 1) {
                    radio_config->antenna_cfg = WIFI_ANTENNA_1X1;
                } else if (antenna == 2) {
                    radio_config->antenna_cfg = WIFI_ANTENNA_2X2;
                } else if (antenna == 3) {
                    radio_config->antenna_cfg = WIFI_ANTENNA_3X3;
                } else if (antenna == 4) {
                    radio_config->antenna_cfg = WIFI_ANTENNA_4X4;
                } else {
                    ALOGI("%s: Invalid antenna cfg value %d", __FUNCTION__,
                          antenna);
                    invalid_radio_cfg = true;
                    continue;
                }
            }
            radio_cfg_size += size_needed;
            num_radio_configurations++;
            result_size += size_needed;
        } /* RADIO_COMBINATIONS_CFGS */
        if (num_radio_configurations) {
            num_radio_combinations++;
            radio_combination_ptr->num_radio_configurations =
                                                    num_radio_configurations;
            ALOGI("%s: radio_combinations[%d]: num_radio_configurations %d",
                  __FUNCTION__, num_radio_combinations,
                  num_radio_configurations);
        }

        buff_ptr = (u8 *)radio_combination_ptr + radio_cfg_size;

        if (max_size_exceeded)
            break;
    } /* RADIO_MATRIX_SUPPORTED_CFGS */
    mRadio_matrix->num_radio_combinations = num_radio_combinations;
    *mRadio_matrix_size = result_size;
    ALOGI("%s: num_radio_combinations %d, radio_matrix_size %d", __FUNCTION__,
          num_radio_combinations, result_size);

    return WIFI_SUCCESS;
}

wifi_error WifihalGeneric::wifiParseRadarHistory() {
{
    // tbVendor
    struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1];
    int rem = 0, num_dfs_entries = 0;

    if (nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX,
          (struct nlattr *)mVendorData,mDataLen, NULL)) {
        ALOGE("%s: nla_parse fail", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }
    if (!tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES]) {
        ALOGE("%s: radar attr entries not present", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    // nested radar history
    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1];
    struct nlattr *attr;
    static struct nla_policy
      policy[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1] = {
            [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ] = { .type = NLA_U32 },
            [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP] = { .type = NLA_U64 },
            [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED] = { .type = NLA_FLAG },
    };
    radar_history_result *newEntry;
    radar_history_result *temp;
    u32 totalEntrySize = 0;
    u32 newEntrySize = sizeof(radar_history_result);

    nla_for_each_nested(attr,
            tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES],
            rem) {
        if ((num_dfs_entries ++) > MAX_NUM_RADAR_HISTORY) {
            ALOGE("%s: exceeded max entries, drop others", __FUNCTION__);
            break;
        }
        if (nla_parse_nested(tb, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX,
                attr, policy)) {
            ALOGI("%s: nla_parse_nested fail", __FUNCTION__);
            continue;
        }
        if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]) {
            ALOGI("%s: radar attr freq not present", __FUNCTION__);
            continue;
        }
        if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]) {
            ALOGI("%s: radar attr timestamp not present", __FUNCTION__);
            continue;
        }

        // realloc buffer for new entry
        temp = (radar_history_result *) realloc(
                mRadarResultParams.entries, totalEntrySize + newEntrySize);
        if (temp == NULL) {
            ALOGE("%s: failed to realloc memory", __FUNCTION__);
            free(mRadarResultParams.entries);
            mRadarResultParams.entries = NULL;
            return WIFI_ERROR_OUT_OF_MEMORY;
        }
        mRadarResultParams.entries = temp;

        newEntry = (radar_history_result *)(
                (u8 *) mRadarResultParams.entries + totalEntrySize);
        memset(newEntry, 0, newEntrySize);
        totalEntrySize += newEntrySize;

        // save to current radar entry
        newEntry->freq = nla_get_u32(
                tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]);
        newEntry->clock_boottime = nla_get_u64(
                tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]);
        newEntry->radar_detected = false;
        if (tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]) {
             newEntry->radar_detected = nla_get_flag(
                     tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]);
        }
        mRadarResultParams.num_entries ++;

        ALOGI("Radar history: freq:%d boottime: %" PRId64 " detected:%d",
                newEntry->freq,
                newEntry->clock_boottime,
                newEntry->radar_detected);
        }
    }

    return WIFI_SUCCESS;
}


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

void WifihalGeneric::getDriverFeatures(features_info *pfeatures)
{
    if (!pfeatures)
        return;

    if (mDriverFeatures.flags != NULL) {
        pfeatures->flags = (u8 *)malloc(mDriverFeatures.flags_len);
        if (pfeatures->flags) {
            memcpy(pfeatures->flags, mDriverFeatures.flags,
                   mDriverFeatures.flags_len);
            pfeatures->flags_len = mDriverFeatures.flags_len;
            return;
        }
    }

    pfeatures->flags_len = 0;
    pfeatures->flags = NULL;
}

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

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

void WifihalGeneric::set_radio_matrix_max_size(u32 max_size) {
    mRadio_matrix_max_size = max_size;
}

void WifihalGeneric::set_radio_matrix_size(u32 *size){
    mRadio_matrix_size = size;
}

void WifihalGeneric::set_radio_matrix(
        wifi_radio_combination_matrix *radio_combination_matrix){
    mRadio_matrix = radio_combination_matrix;
}

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;
}

void WifihalGeneric::set_channels_buff(wifi_usable_channel* channels)
{
    channel_buff = channels;
    memset(channel_buff, 0, sizeof(wifi_usable_channel) * mSetSizeMax);
}

u32 WifihalGeneric::get_results_size(void)
{
    return res_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;
}

wifi_error WifihalGeneric::copyCachedRadarHistory(
        radar_history_result *resultBuf, int resultBufSize, int *numResults) {
    *numResults = 0;

    if (mRadarResultParams.entries) {
        radar_history_result *sEntry = NULL;
        radar_history_result *tEntry = NULL;
        u32 offset = 0;
        int i;

        for (i = 0; i < mRadarResultParams.num_entries; i ++) {
            if (resultBufSize < (offset + sizeof(radar_history_result))) {
                break;
            }

            sEntry = (radar_history_result *)(
                           (u8 *) mRadarResultParams.entries + offset);
            tEntry = (radar_history_result *)(
                           (u8 *) resultBuf + offset);
            memcpy(tEntry, sEntry, sizeof(radar_history_result));
            (*numResults) += 1;
            offset += sizeof(radar_history_result);
        }
    }

    return WIFI_SUCCESS;
}

void WifihalGeneric::freeCachedRadarHistory() {
    if (mRadarResultParams.entries) {
        free(mRadarResultParams.entries);
        mRadarResultParams.entries = NULL;
        mRadarResultParams.num_entries = 0;
    }
}



wifi_error WifihalGeneric::getSarVersion(wifi_interface_handle handle)
{
    wifi_error ret;
    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;
    }

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

    return ret;
}


