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

 * Changes from Qualcomm Innovation Center are provided under the following license:

 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 */

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

#include "common.h"
#include "cpp_bindings.h"
#include "gscancommand.h"
#include "gscan_event_handler.h"
#include "vendor_definitions.h"

#define GSCAN_EVENT_WAIT_TIME_SECONDS 4
#define WIFI_SCANNING_MAC_OUI_LENGTH 3
#define EPNO_NO_NETWORKS 0

/* BSSID blacklist */
typedef struct {
    int num_bssid;                           // number of blacklisted BSSIDs
    mac_addr bssids[MAX_BLACKLIST_BSSID];    // blacklisted BSSIDs
} wifi_bssid_params;

/* Used to handle gscan command events from driver/firmware.*/
typedef struct gscan_event_handlers_s {
    GScanCommandEventHandler *gscanStartCmdEventHandler;
    GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler;
    GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler;
    GScanCommandEventHandler *gScanSetSsidHotlistCmdEventHandler;
    GScanCommandEventHandler *gScanSetPnoListCmdEventHandler;
    GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler;
} gscan_event_handlers;

wifi_error initializeGscanHandlers(hal_info *info)
{
    info->gscan_handlers = (gscan_event_handlers *)malloc(sizeof(gscan_event_handlers));
    if (info->gscan_handlers) {
        memset(info->gscan_handlers, 0, sizeof(gscan_event_handlers));
    }
    else {
        ALOGE("%s: Allocation of gscan event handlers failed",
              __FUNCTION__);
        return WIFI_ERROR_OUT_OF_MEMORY;
    }
    return WIFI_SUCCESS;
}

wifi_error cleanupGscanHandlers(hal_info *info)
{
    gscan_event_handlers* event_handlers;
    if (info && info->gscan_handlers) {
        event_handlers = (gscan_event_handlers*) info->gscan_handlers;
        if (event_handlers->gscanStartCmdEventHandler) {
            delete event_handlers->gscanStartCmdEventHandler;
        }
        if (event_handlers->gScanSetBssidHotlistCmdEventHandler) {
            delete event_handlers->gScanSetBssidHotlistCmdEventHandler;
        }
        if (event_handlers->gScanSetSignificantChangeCmdEventHandler) {
            delete event_handlers->gScanSetSignificantChangeCmdEventHandler;
        }
        if (event_handlers->gScanSetSsidHotlistCmdEventHandler) {
            delete event_handlers->gScanSetSsidHotlistCmdEventHandler;
        }
        if (event_handlers->gScanSetPnoListCmdEventHandler) {
            delete event_handlers->gScanSetPnoListCmdEventHandler;
        }
        if (event_handlers->gScanPnoSetPasspointListCmdEventHandler) {
            delete event_handlers->gScanPnoSetPasspointListCmdEventHandler;
        }
        memset(event_handlers, 0, sizeof(gscan_event_handlers));
        free(info->gscan_handlers);
        info->gscan_handlers = NULL;
        return WIFI_SUCCESS;
    }
    ALOGE ("%s: info or info->gscan_handlers NULL", __FUNCTION__);
    return WIFI_ERROR_UNKNOWN;
}

/* Implementation of the API functions exposed in gscan.h */
wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
       int band, int max_channels, wifi_channel *channels, int *num_channels)
{
    int requestId;
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(handle);
    wifi_handle wifiHandle = getWifiHandle(handle);

    /* No request id from caller, so generate one and pass it on to the driver.
     * Generate one randomly.
     */
    requestId = get_requestid();
    ALOGV("%s: RequestId:%d band:%d max_channels:%d", __FUNCTION__,
          requestId, band, max_channels);

    if (channels == NULL) {
        ALOGE("%s: NULL channels pointer provided. Exit.",
            __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    gScanCommand = new GScanCommand(
                            wifiHandle,
                            requestId,
                            OUI_QCA,
                            QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }
    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData)
        goto cleanup;

    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            requestId) ||
        gScanCommand->put_u32(
        QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND,
            band) ||
        gScanCommand->put_u32(
        QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS,
            max_channels) )
    {
        goto cleanup;
    }
    gScanCommand->attr_end(nlData);
    /* Populate the input received from caller/framework. */
    gScanCommand->setMaxChannels(max_channels);
    gScanCommand->setChannels(channels);
    gScanCommand->setNumChannelsPtr(num_channels);

    /* Send the msg and wait for a response. */
    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);

cleanup:
    delete gScanCommand;
    return ret;
}

wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
                                 wifi_gscan_capabilities *capabilities)
{
    wifi_handle wifiHandle = getWifiHandle(handle);
    hal_info *info = getHalInfo(wifiHandle);

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver", __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if (capabilities == NULL) {
        ALOGE("%s: NULL capabilities pointer provided. Exit.", __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    memcpy(capabilities, &info->capa.gscan_capa, sizeof(wifi_gscan_capabilities));

    return WIFI_SUCCESS;
}

wifi_error wifi_start_gscan(wifi_request_id id,
                            wifi_interface_handle iface,
                            wifi_scan_cmd_params params,
                            wifi_scan_result_handler handler)
{
    wifi_error ret;
    u32 i, j;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    u32 num_scan_buckets, numChannelSpecs;
    wifi_scan_bucket_spec bucketSpec;
    struct nlattr *nlBuckectSpecList;
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanStartCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    ALOGV("%s: RequestId:%d ", __FUNCTION__, id);
    /* Wi-Fi HAL doesn't need to check if a similar request to start gscan was
     *  made earlier. If start_gscan() is called while another gscan is already
     *  running, the request will be sent down to driver and firmware. If new
     * request is successfully honored, then Wi-Fi HAL will use the new request
     * id for the gScanStartCmdEventHandler object.
     */
    gScanCommand = new GScanCommand(
                                wifiHandle,
                                id,
                                OUI_QCA,
                                QCA_NL80211_VENDOR_SUBCMD_GSCAN_START);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    num_scan_buckets = (unsigned int)params.num_buckets > MAX_BUCKETS ?
                            MAX_BUCKETS : params.num_buckets;

    ALOGV("%s: Base Period:%d Max_ap_per_scan:%d "
          "Threshold_percent:%d Threshold_num_scans:%d "
          "num_buckets:%d", __FUNCTION__, params.base_period,
          params.max_ap_per_scan, params.report_threshold_percent,
          params.report_threshold_num_scans, num_scan_buckets);
    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD,
            params.base_period) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN,
            params.max_ap_per_scan) ||
        gScanCommand->put_u8(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT,
            params.report_threshold_percent) ||
        gScanCommand->put_u8(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS,
            params.report_threshold_num_scans) ||
        gScanCommand->put_u8(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS,
            num_scan_buckets))
    {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    nlBuckectSpecList =
        gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC);
    /* Add NL attributes for scan bucket specs . */
    for (i = 0; i < num_scan_buckets; i++) {
        bucketSpec = params.buckets[i];
        numChannelSpecs = (unsigned int)bucketSpec.num_channels > MAX_CHANNELS ?
                                MAX_CHANNELS : bucketSpec.num_channels;

        ALOGV("%s: Index: %d Bucket Id:%d Band:%d Period:%d ReportEvent:%d "
              "numChannelSpecs:%d max_period:%d base:%d step_count:%d",
              __FUNCTION__, i, bucketSpec.bucket, bucketSpec.band,
              bucketSpec.period, bucketSpec.report_events,
              numChannelSpecs, bucketSpec.max_period,
              bucketSpec.base, bucketSpec.step_count);

        struct nlattr *nlBucketSpec = gScanCommand->attr_start(i);
        if (gScanCommand->put_u8(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX,
                bucketSpec.bucket) ||
            gScanCommand->put_u8(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND,
                bucketSpec.band) ||
            gScanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD,
                bucketSpec.period) ||
            gScanCommand->put_u8(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS,
                bucketSpec.report_events) ||
            gScanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS,
                numChannelSpecs) ||
            gScanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_MAX_PERIOD,
                bucketSpec.max_period) ||
            gScanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BASE,
                bucketSpec.base) ||
            gScanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_STEP_COUNT,
                bucketSpec.step_count))
        {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }

        struct nlattr *nl_channelSpecList =
            gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC);

        /* Add NL attributes for scan channel specs . */
        for (j = 0; j < numChannelSpecs; j++) {
            struct nlattr *nl_channelSpec = gScanCommand->attr_start(j);
            wifi_scan_channel_spec channel_spec = bucketSpec.channels[j];

            ALOGV("%s: Channel Spec Index:%d Channel:%d Dwell Time:%d "
                  "passive:%d", __FUNCTION__, j, channel_spec.channel,
                  channel_spec.dwellTimeMs, channel_spec.passive);

            if ( gScanCommand->put_u32(
                    QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL,
                    channel_spec.channel) ||
                gScanCommand->put_u32(
                    QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME,
                    channel_spec.dwellTimeMs) ||
                gScanCommand->put_u8(
                    QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE,
                    channel_spec.passive) )
            {
                ret = WIFI_ERROR_UNKNOWN;
                goto cleanup;
            }

            gScanCommand->attr_end(nl_channelSpec);
        }
        gScanCommand->attr_end(nl_channelSpecList);
        gScanCommand->attr_end(nlBucketSpec);
    }
    gScanCommand->attr_end(nlBuckectSpecList);

    gScanCommand->attr_end(nlData);

    /* Set the callback handler functions for related events. */
    GScanCallbackHandler callbackHandler;
    memset(&callbackHandler, 0, sizeof(callbackHandler));
    callbackHandler.on_full_scan_result = handler.on_full_scan_result;
    callbackHandler.on_scan_event = handler.on_scan_event;

    /* Create an object to handle the related events from firmware/driver. */
    if (gScanStartCmdEventHandler == NULL) {
        gScanStartCmdEventHandler = new GScanCommandEventHandler(
                                    wifiHandle,
                                    id,
                                    OUI_QCA,
                                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_START,
                                    callbackHandler);
        if (gScanStartCmdEventHandler == NULL) {
            ALOGE("%s: Error gScanStartCmdEventHandler NULL", __FUNCTION__);
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        event_handlers->gscanStartCmdEventHandler = gScanStartCmdEventHandler;
    } else {
        gScanStartCmdEventHandler->setCallbackHandler(callbackHandler);
    }

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s : requestResponse Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanStartCmdEventHandler != NULL) {
        gScanStartCmdEventHandler->set_request_id(id);
        gScanStartCmdEventHandler->enableEventHandling();
    }

cleanup:
    delete gScanCommand;
    /* Disable Event Handling if ret != 0 */
    if ((ret != WIFI_SUCCESS) && gScanStartCmdEventHandler) {
        ALOGI("%s: Error ret:%d, disable event handling",
            __FUNCTION__, ret);
        gScanStartCmdEventHandler->disableEventHandling();
    }
    return ret;

}

wifi_error wifi_stop_gscan(wifi_request_id id,
                            wifi_interface_handle iface)
{
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;

    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanStartCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if (gScanStartCmdEventHandler == NULL ||
        gScanStartCmdEventHandler->isEventHandlingEnabled() == false) {
        ALOGE("%s: GSCAN isn't running or already stopped. "
            "Nothing to do. Exit", __FUNCTION__);
        return WIFI_ERROR_NOT_AVAILABLE;
    }

    gScanCommand = new GScanCommand(
                                wifiHandle,
                                id,
                                OUI_QCA,
                                QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ret = gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    gScanCommand->attr_end(nlData);

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);

    /* Disable Event Handling. */
    if (gScanStartCmdEventHandler) {
        gScanStartCmdEventHandler->disableEventHandling();
    }

cleanup:
    delete gScanCommand;
    return ret;
}

/* Set the GSCAN BSSID Hotlist. */
wifi_error wifi_set_bssid_hotlist(wifi_request_id id,
                                    wifi_interface_handle iface,
                                    wifi_bssid_hotlist_params params,
                                    wifi_hotlist_ap_found_handler handler)
{
    int i, numAp;
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData, *nlApThresholdParamList;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanSetBssidHotlistCmdEventHandler =
        event_handlers->gScanSetBssidHotlistCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    /* Wi-Fi HAL doesn't need to check if a similar request to set bssid
     * hotlist was made earlier. If set_bssid_hotlist() is called while
     * another one is running, the request will be sent down to driver and
     * firmware. If the new request is successfully honored, then Wi-Fi HAL
     * will use the new request id for the gScanSetBssidHotlistCmdEventHandler
     * object.
     */

    gScanCommand =
        new GScanCommand(
                    wifiHandle,
                    id,
                    OUI_QCA,
                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    numAp = (unsigned int)params.num_bssid > MAX_HOTLIST_APS ?
        MAX_HOTLIST_APS : params.num_bssid;
    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE,
            params.lost_ap_sample_size) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP,
            numAp))
    {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ALOGV("%s: lost_ap_sample_size:%d numAp:%d", __FUNCTION__,
          params.lost_ap_sample_size, numAp);
    /* Add the vendor specific attributes for the NL command. */
    nlApThresholdParamList =
        gScanCommand->attr_start(
                                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM);
    if (!nlApThresholdParamList){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    /* Add nested NL attributes for AP Threshold Param. */
    for (i = 0; i < numAp; i++) {
        ap_threshold_param apThreshold = params.ap[i];
        struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i);
        if (!nlApThresholdParam){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        if (gScanCommand->put_addr(
                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID,
                apThreshold.bssid) ||
            gScanCommand->put_s32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW,
                apThreshold.low) ||
            gScanCommand->put_s32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH,
                apThreshold.high))
        {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        ALOGV("%s: Index:%d BssId: %hhx:%hhx:%hhx:%hhx:%hhx:%hhx "
              "Threshold low:%d high:%d", __FUNCTION__, i,
              apThreshold.bssid[0], apThreshold.bssid[1],
              apThreshold.bssid[2], apThreshold.bssid[3],
              apThreshold.bssid[4], apThreshold.bssid[5],
              apThreshold.low, apThreshold.high);
        gScanCommand->attr_end(nlApThresholdParam);
    }

    gScanCommand->attr_end(nlApThresholdParamList);

    gScanCommand->attr_end(nlData);

    GScanCallbackHandler callbackHandler;
    memset(&callbackHandler, 0, sizeof(callbackHandler));
    callbackHandler.on_hotlist_ap_found = handler.on_hotlist_ap_found;
    callbackHandler.on_hotlist_ap_lost = handler.on_hotlist_ap_lost;

    /* Create an object of the event handler class to take care of the
      * asychronous events on the north-bound.
      */
    if (gScanSetBssidHotlistCmdEventHandler == NULL) {
        gScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler(
                            wifiHandle,
                            id,
                            OUI_QCA,
                            QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST,
                            callbackHandler);
        if (gScanSetBssidHotlistCmdEventHandler == NULL) {
            ALOGE("%s: Error instantiating "
                "gScanSetBssidHotlistCmdEventHandler.", __FUNCTION__);
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        event_handlers->gScanSetBssidHotlistCmdEventHandler =
            gScanSetBssidHotlistCmdEventHandler;
    } else {
        gScanSetBssidHotlistCmdEventHandler->setCallbackHandler(callbackHandler);
    }

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanSetBssidHotlistCmdEventHandler != NULL) {
        gScanSetBssidHotlistCmdEventHandler->set_request_id(id);
        gScanSetBssidHotlistCmdEventHandler->enableEventHandling();
    }

cleanup:
    delete gScanCommand;
    /* Disable Event Handling if ret != 0 */
    if ((ret != WIFI_SUCCESS) && gScanSetBssidHotlistCmdEventHandler) {
        ALOGI("%s: Error ret:%d, disable event handling",
            __FUNCTION__, ret);
        gScanSetBssidHotlistCmdEventHandler->disableEventHandling();
    }
    return ret;
}

wifi_error wifi_reset_bssid_hotlist(wifi_request_id id,
                            wifi_interface_handle iface)
{
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanSetBssidHotlistCmdEventHandler =
        event_handlers->gScanSetBssidHotlistCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if (gScanSetBssidHotlistCmdEventHandler == NULL ||
        (gScanSetBssidHotlistCmdEventHandler->isEventHandlingEnabled() ==
         false)) {
        ALOGE("wifi_reset_bssid_hotlist: GSCAN bssid_hotlist isn't set. "
            "Nothing to do. Exit");
        return WIFI_ERROR_NOT_AVAILABLE;
    }

    gScanCommand = new GScanCommand(
                        wifiHandle,
                        id,
                        OUI_QCA,
                        QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST);

    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ret = gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    gScanCommand->attr_end(nlData);

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);

    /* Disable Event Handling. */
    if (gScanSetBssidHotlistCmdEventHandler) {
        gScanSetBssidHotlistCmdEventHandler->disableEventHandling();
    }

cleanup:
    delete gScanCommand;
    return ret;
}

/* Set the GSCAN Significant AP Change list. */
wifi_error wifi_set_significant_change_handler(wifi_request_id id,
                                            wifi_interface_handle iface,
                                    wifi_significant_change_params params,
                                    wifi_significant_change_handler handler)
{
    int i, numAp;
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData, *nlApThresholdParamList;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanSetSignificantChangeCmdEventHandler =
        event_handlers->gScanSetSignificantChangeCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    /* Wi-Fi HAL doesn't need to check if a similar request to set significant
     * change list was made earlier. If set_significant_change() is called while
     * another one is running, the request will be sent down to driver and
     * firmware. If the new request is successfully honored, then Wi-Fi HAL
     * will use the new request id for the gScanSetSignificantChangeCmdEventHandler
     * object.
     */

    gScanCommand = new GScanCommand(
                    wifiHandle,
                    id,
                    OUI_QCA,
                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    numAp = (unsigned int)params.num_bssid > MAX_SIGNIFICANT_CHANGE_APS ?
        MAX_SIGNIFICANT_CHANGE_APS : params.num_bssid;

    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id) ||
        gScanCommand->put_u32(
        QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE,
            params.rssi_sample_size) ||
        gScanCommand->put_u32(
        QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE,
            params.lost_ap_sample_size) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING,
            params.min_breaching) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP,
            numAp))
    {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ALOGV("%s: Number of AP params:%d Rssi_sample_size:%d "
          "lost_ap_sample_size:%d min_breaching:%d", __FUNCTION__,
          numAp, params.rssi_sample_size, params.lost_ap_sample_size,
          params.min_breaching);

    /* Add the vendor specific attributes for the NL command. */
    nlApThresholdParamList =
        gScanCommand->attr_start(
                                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM);
    if (!nlApThresholdParamList){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }
    /* Add nested NL attributes for AP Threshold Param list. */
    for (i = 0; i < numAp; i++) {
        ap_threshold_param apThreshold = params.ap[i];
        struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i);
        if (!nlApThresholdParam){
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        if ( gScanCommand->put_addr(
                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID,
                apThreshold.bssid) ||
            gScanCommand->put_s32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW,
                apThreshold.low) ||
            gScanCommand->put_s32(
                QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH,
                apThreshold.high))
        {
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        ALOGV("%s: ap[%d].bssid:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx "
              "ap[%d].low:%d  ap[%d].high:%d", __FUNCTION__,
              i,
              apThreshold.bssid[0], apThreshold.bssid[1],
              apThreshold.bssid[2], apThreshold.bssid[3],
              apThreshold.bssid[4], apThreshold.bssid[5],
              i, apThreshold.low, i, apThreshold.high);
        gScanCommand->attr_end(nlApThresholdParam);
    }

    gScanCommand->attr_end(nlApThresholdParamList);

    gScanCommand->attr_end(nlData);

    GScanCallbackHandler callbackHandler;
    memset(&callbackHandler, 0, sizeof(callbackHandler));
    callbackHandler.on_significant_change = handler.on_significant_change;

    /* Create an object of the event handler class to take care of the
      * asychronous events on the north-bound.
      */
    if (gScanSetSignificantChangeCmdEventHandler == NULL) {
        gScanSetSignificantChangeCmdEventHandler =
            new GScanCommandEventHandler(
                     wifiHandle,
                     id,
                     OUI_QCA,
                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE,
                     callbackHandler);
        if (gScanSetSignificantChangeCmdEventHandler == NULL) {
            ALOGE("%s: Error in instantiating, "
                "gScanSetSignificantChangeCmdEventHandler.",
                __FUNCTION__);
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        event_handlers->gScanSetSignificantChangeCmdEventHandler =
            gScanSetSignificantChangeCmdEventHandler;
    } else {
        gScanSetSignificantChangeCmdEventHandler->setCallbackHandler(callbackHandler);
    }

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanSetSignificantChangeCmdEventHandler != NULL) {
        gScanSetSignificantChangeCmdEventHandler->set_request_id(id);
        gScanSetSignificantChangeCmdEventHandler->enableEventHandling();
    }

cleanup:
    /* Disable Event Handling if ret != 0 */
    if ((ret != WIFI_SUCCESS) && gScanSetSignificantChangeCmdEventHandler) {
        ALOGI("%s: Error ret:%d, disable event handling",
            __FUNCTION__, ret);
        gScanSetSignificantChangeCmdEventHandler->disableEventHandling();
    }
    delete gScanCommand;
    return ret;
}

/* Clear the GSCAN Significant AP change list. */
wifi_error wifi_reset_significant_change_handler(wifi_request_id id,
                                            wifi_interface_handle iface)
{
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanSetSignificantChangeCmdEventHandler =
        event_handlers->gScanSetSignificantChangeCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if (gScanSetSignificantChangeCmdEventHandler == NULL ||
        (gScanSetSignificantChangeCmdEventHandler->isEventHandlingEnabled() ==
        false)) {
        ALOGE("wifi_reset_significant_change_handler: GSCAN significant_change"
            " isn't set. Nothing to do. Exit");
        return WIFI_ERROR_NOT_AVAILABLE;
    }

    gScanCommand =
        new GScanCommand
                    (
                    wifiHandle,
                    id,
                    OUI_QCA,
                    QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ret = gScanCommand->put_u32(
                    QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
                    id);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    gScanCommand->attr_end(nlData);

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);

    /* Disable Event Handling. */
    if (gScanSetSignificantChangeCmdEventHandler) {
        gScanSetSignificantChangeCmdEventHandler->disableEventHandling();
    }

cleanup:
    delete gScanCommand;
    return ret;
}

/* Get the GSCAN cached scan results. */
wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface,
                                            byte flush, int max,
                                            wifi_cached_scan_results *results,
                                            int *num)
{
    int requestId, retRequestRsp = 0;
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;

    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) {
        ALOGE("%s: GSCAN is not supported by driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    /* No request id from caller, so generate one and pass it on to the driver. */
    /* Generate it randomly */
    requestId = get_requestid();

    if (results == NULL || num == NULL) {
        ALOGE("%s: NULL pointer provided. Exit.",
            __FUNCTION__);
        return WIFI_ERROR_INVALID_ARGS;
    }

    gScanCommand = new GScanCommand(
                        wifiHandle,
                        requestId,
                        OUI_QCA,
                        QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

    ret = gScanCommand->allocRspParams(eGScanGetCachedResultsRspParams);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Failed to allocate memory for response struct. Error:%d",
            __FUNCTION__, ret);
        goto cleanup;
    }

    ret = gScanCommand->allocCachedResultsTemp(max, results);
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: Failed to allocate memory for temp gscan cached list. "
            "Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    /* Clear the destination cached results list before copying results. */
    memset(results, 0, max * sizeof(wifi_cached_scan_results));

    /* Create the NL message. */
    ret = gScanCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Set the interface Id of the message. */
    ret = gScanCommand->set_iface_id(ifaceInfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    if (gScanCommand->put_u32(
         QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            requestId) ||
        gScanCommand->put_u8(
         QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH,
            flush) ||
        gScanCommand->put_u32(
         QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX,
            max))
    {
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ALOGV("%s: flush:%d max:%d", __FUNCTION__, flush, max);
    gScanCommand->attr_end(nlData);

    retRequestRsp = gScanCommand->requestResponse();
    if (retRequestRsp != 0) {
        ALOGE("%s: requestResponse Error:%d",
            __FUNCTION__, retRequestRsp);
        /* It's possible to get ETIMEDOUT after receiving few results from
         * driver. Copy and forward them to framework.
         */
        if (retRequestRsp != -ETIMEDOUT) {
            /* Proceed to cleanup & return no results */
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
    }

    /* No more data, copy the parsed results into the caller's results array */
    ret = gScanCommand->copyCachedScanResults(num, results);
    ALOGV("%s: max: %d, num:%d", __FUNCTION__, max, *num);

    if (!ret) {
        /* If requestResponse returned a TIMEOUT */
        if (retRequestRsp == -ETIMEDOUT) {
            if (*num > 0) {
                /* Mark scan results as incomplete for the last scan_id */
                results[(*num)-1].flags = WIFI_SCAN_FLAG_INTERRUPTED;
                ALOGV("%s: Timeout happened. Mark scan results as incomplete "
                    "for scan_id:%d", __FUNCTION__, results[(*num)-1].scan_id);
                ret = WIFI_SUCCESS;
            } else
                ret = WIFI_ERROR_TIMED_OUT;
        }
    }
cleanup:
    gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams);
    delete gScanCommand;
    return ret;
}

/* Random MAC OUI for PNO */
wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui)
{
    wifi_error ret;
    struct nlattr *nlData;
    WifiVendorCommand *vCommand = NULL;
    interface_info *iinfo = getIfaceInfo(handle);
    wifi_handle wifiHandle = getWifiHandle(handle);

    vCommand = new WifiVendorCommand(wifiHandle, 0,
            OUI_QCA,
            QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI);
    if (vCommand == NULL) {
        ALOGE("%s: Error vCommand NULL", __FUNCTION__);
        return WIFI_ERROR_OUT_OF_MEMORY;
    }

    /* create the message */
    ret = vCommand->create();
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    ret = vCommand->set_iface_id(iinfo->name);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    /* Add the vendor specific attributes for the NL command. */
    nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData){
        ret = WIFI_ERROR_UNKNOWN;
        goto cleanup;
    }

    ALOGV("%s: MAC_OUI - %02x:%02x:%02x", __FUNCTION__,
          scan_oui[0], scan_oui[1], scan_oui[2]);

    /* Add the fixed part of the mac_oui to the nl command */
    ret = vCommand->put_bytes(
            QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI,
            (char *)scan_oui,
            WIFI_SCANNING_MAC_OUI_LENGTH);
    if (ret != WIFI_SUCCESS)
        goto cleanup;

    vCommand->attr_end(nlData);

    ret = vCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

cleanup:
    delete vCommand;
    return ret;
}


GScanCommand::GScanCommand(wifi_handle handle, int id, u32 vendor_id,
                                  u32 subcmd)
        : WifiVendorCommand(handle, id, vendor_id, subcmd)
{
    /* Initialize the member data variables here */
    mGetCachedResultsRspParams = NULL;
    mChannels = NULL;
    mMaxChannels = 0;
    mNumChannelsPtr = NULL;

    mRequestId = id;
    memset(&mHandler, 0,sizeof(mHandler));
}

GScanCommand::~GScanCommand()
{
    unregisterVendorHandler(mVendor_id, mSubcmd);
}


/* This function implements creation of Vendor command */
wifi_error GScanCommand::create() {
    wifi_error ret;

    ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
    if (ret != WIFI_SUCCESS)
        return ret;

    /* Insert the oui in the msg */
    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
    if (ret != WIFI_SUCCESS)
        return ret;

    /* Insert the subcmd in the msg */
    ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
    if (ret != WIFI_SUCCESS)
        return ret;

     ALOGV("%s: mVendor_id = %d, Subcmd = %d.",
        __FUNCTION__, mVendor_id, mSubcmd);

    return ret;
}

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

int GScanCommand::handleResponse(WifiEvent &reply)
{
    int i = 0;
    wifi_error ret = WIFI_ERROR_UNKNOWN;
    u32 val;

    WifiVendorCommand::handleResponse(reply);

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

    switch(mSubcmd)
    {
        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS:
        {
            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]) {
                ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS"
                    " not found", __FUNCTION__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            val = nla_get_u32(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]);

            val = val > (unsigned int)mMaxChannels ?
                    (unsigned int)mMaxChannels : val;
            *mNumChannelsPtr = val;

            /* Extract the list of channels. */
            if (*mNumChannelsPtr > 0 ) {
                if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS]) {
                    ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS"
                        " not found", __FUNCTION__);
                    ret = WIFI_ERROR_INVALID_ARGS;
                    break;
                }
                nla_memcpy(mChannels,
                    tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS],
                    sizeof(wifi_channel) * (*mNumChannelsPtr));
            }
            char buf[256];
            size_t len = 0;
            for (i = 0; i < *mNumChannelsPtr && len < sizeof(buf); i++) {
                 len +=  snprintf(buf + len, sizeof(buf) - len, "%u ",
                                  *(mChannels + i));
            }
            ALOGV("%s: Num Channels %d: List of valid channels are: %s",
                  __FUNCTION__, *mNumChannelsPtr, buf);

        }
        break;
        case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS:
        {
            wifi_request_id id;
            u32 numResults = 0;
            int firstScanIdInPatch = -1;

            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
                ALOGE("%s: GSCAN_RESULTS_REQUEST_ID not"
                    "found", __FUNCTION__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            id = nla_get_u32(
                    tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
                    );
            /* If this is not for us, just ignore it. */
            if (id != mRequestId) {
                ALOGV("%s: Event has Req. ID:%d <> ours:%d",
                    __FUNCTION__, id, mRequestId);
                break;
            }
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not"
                    "found", __FUNCTION__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }
            /* Read num of cached scan results in this data chunk. Note that
             * this value doesn't represent the number of unique gscan scan Ids
             * since the first scan id in this new chunk could be similar to
             * the last scan id in the previous chunk.
             */
            numResults = nla_get_u32(tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
            ALOGV("%s: num Cached results in this fragment:%d",
                       __FUNCTION__, numResults);

            if (!mGetCachedResultsRspParams) {
                ALOGE("%s: mGetCachedResultsRspParams is NULL, exit.",
                    __FUNCTION__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }

            /* To support fragmentation from firmware, monitor the
             * MORE_DATA flag and cache results until MORE_DATA = 0.
             */
            if (!tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
                ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA "
                    "not found", __FUNCTION__);
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            } else {
                mGetCachedResultsRspParams->more_data = nla_get_u8(
                    tbVendor[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
            }

            /* No data in this chunk so skip this chunk */
            if (numResults == 0) {
                return NL_SKIP;
            }

            if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID]) {
                ALOGE("GSCAN_CACHED_RESULTS_SCAN_ID not found");
                ret = WIFI_ERROR_INVALID_ARGS;
                break;
            }

            /* Get the first Scan-Id in this chuck of cached results. */
            firstScanIdInPatch = nla_get_u32(tbVendor[
                    QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID]);

            ALOGV("More data: %d, firstScanIdInPatch: %d, lastProcessedScanId: %d",
                mGetCachedResultsRspParams->more_data, firstScanIdInPatch,
                mGetCachedResultsRspParams->lastProcessedScanId);

            if (numResults) {
                if (firstScanIdInPatch !=
                    mGetCachedResultsRspParams->lastProcessedScanId) {
                    /* New result scan Id block, update the starting index. */
                    mGetCachedResultsRspParams->cachedResultsStartingIndex++;
                }

                ret = gscan_get_cached_results(
                                    mGetCachedResultsRspParams->cached_results,
                                    tbVendor);
                /* If a parsing error occurred, exit and proceed for cleanup. */
                if (ret)
                    break;
            }
        }
        break;
        default:
            /* Error case should not happen print log */
            ALOGE("%s: Wrong GScan subcmd response received %d",
                __FUNCTION__, mSubcmd);
    }

    /* A parsing error occurred, do the cleanup of gscan result lists. */
    if (ret) {
        switch(mSubcmd)
        {
            case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS:
            {
                ALOGE("%s: Parsing error, free CachedResultsRspParams",
                    __FUNCTION__);
                freeRspParams(eGScanGetCachedResultsRspParams);
            }
            break;
            default:
                ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd);
        }
    }
    return NL_SKIP;
}

/* Called to parse and extract cached results. */
wifi_error GScanCommand:: gscan_get_cached_results(
                                      wifi_cached_scan_results *cached_results,
                                      struct nlattr **tb_vendor)
{
    int j = 0;
    struct nlattr *scanResultsInfo, *wifiScanResultsInfo;
    int rem = 0, remResults = 0;
    u32 len = 0, numScanResults = 0;
    int i = mGetCachedResultsRspParams->cachedResultsStartingIndex;
    ALOGV("%s: starting counter: %d", __FUNCTION__, i);

    for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
               QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST]),
               rem = nla_len(tb_vendor[
               QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST]);
           nla_ok(scanResultsInfo, rem) && i < mGetCachedResultsRspParams->max;
           scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
       {
           struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
           nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
           (struct nlattr *) nla_data(scanResultsInfo),
                   nla_len(scanResultsInfo), NULL);

           if (!
               tb2[
                   QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID
                   ])
           {
               ALOGE("%s: GSCAN_CACHED_RESULTS_SCAN_ID"
                   " not found", __FUNCTION__);
               return WIFI_ERROR_INVALID_ARGS;
           }
           cached_results[i].scan_id =
               nla_get_u32(
               tb2[
                   QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID
                   ]);

           if (!
               tb2[
                   QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS
                   ])
           {
               ALOGE("%s: GSCAN_CACHED_RESULTS_FLAGS "
                   "not found", __FUNCTION__);
               return WIFI_ERROR_INVALID_ARGS;
           }
           cached_results[i].flags =
               nla_get_u32(
               tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS]);

           if (!tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED])
           {
               ALOGI("%s: GSCAN_RESULTS_BUCKETS_SCANNED"
                   "not found", __FUNCTION__);
           } else {
               cached_results[i].buckets_scanned = nla_get_u32(
                       tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]);
           }

           if (!
               tb2[
                   QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE
                   ])
           {
               ALOGE("%s: RESULTS_NUM_RESULTS_AVAILABLE "
                   "not found", __FUNCTION__);
               return WIFI_ERROR_INVALID_ARGS;
           }
           numScanResults =
               nla_get_u32(
               tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);

           if (mGetCachedResultsRspParams->lastProcessedScanId !=
                                        cached_results[i].scan_id) {
               j = 0; /* reset wifi_scan_result counter */
               cached_results[i].num_results = 0;
               ALOGV("parsing: *lastProcessedScanId [%d] !="
                     " cached_results[%d].scan_id:%d, j:%d "
                     "numScanResults: %d",
                     mGetCachedResultsRspParams->lastProcessedScanId, i,
                     cached_results[i].scan_id, j, numScanResults);
               mGetCachedResultsRspParams->lastProcessedScanId =
                   cached_results[i].scan_id;
               mGetCachedResultsRspParams->wifiScanResultsStartingIndex = 0;
               /* Increment the number of cached scan results received */
               mGetCachedResultsRspParams->num_cached_results++;
           } else {
               j = mGetCachedResultsRspParams->wifiScanResultsStartingIndex;
               ALOGV("parsing: *lastProcessedScanId [%d] == "
                     "cached_results[%d].scan_id:%d, j:%d "
                     "numScanResults:%d",
                     mGetCachedResultsRspParams->lastProcessedScanId, i,
                     cached_results[i].scan_id, j, numScanResults);
           }

           ALOGV("%s: scan_id %d ", __FUNCTION__,
            cached_results[i].scan_id);
           ALOGV("%s: flags  %u ", __FUNCTION__,
            cached_results[i].flags);

           for (wifiScanResultsInfo = (struct nlattr *) nla_data(tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
                remResults = nla_len(tb2[
                QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
                nla_ok(wifiScanResultsInfo, remResults);
                wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(remResults)))
           {
                struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
                nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
                        (struct nlattr *) nla_data(wifiScanResultsInfo),
                        nla_len(wifiScanResultsInfo), NULL);
                if (j < MAX_AP_CACHE_PER_SCAN) {
                    if (!
                        tb3[
                           QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
                           ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_TIME_STAMP not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    cached_results[i].results[j].ts =
                        nla_get_u64(
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
                            ]);
                    if (!
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
                            ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_SSID not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    len = nla_len(tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
                    len =
                        sizeof(cached_results[i].results[j].ssid) <= len ?
                        sizeof(cached_results[i].results[j].ssid) : len;
                    memcpy((void *)&cached_results[i].results[j].ssid,
                        nla_data(
                        tb3[
                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]),
                        len);
                    if (!
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
                            ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_BSSID not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    len = nla_len(
                        tb3[
                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
                    len =
                        sizeof(cached_results[i].results[j].bssid) <= len ?
                        sizeof(cached_results[i].results[j].bssid) : len;
                    memcpy(&cached_results[i].results[j].bssid,
                        nla_data(
                        tb3[
                        QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]),
                        len);
                    if (!
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
                            ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_CHANNEL not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    cached_results[i].results[j].channel =
                        nla_get_u32(
                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
                    if (!
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
                            ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_RSSI not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    cached_results[i].results[j].rssi =
                        get_s32(
                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
                    if (!
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
                            ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_RTT not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    cached_results[i].results[j].rtt =
                        nla_get_u32(
                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
                    if (!
                        tb3[
                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
                        ])
                    {
                        ALOGE("%s: "
                            "RESULTS_SCAN_RESULT_RTT_SD not found",
                            __FUNCTION__);
                        return WIFI_ERROR_INVALID_ARGS;
                    }
                    cached_results[i].results[j].rtt_sd =
                        nla_get_u32(
                        tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
#ifdef QC_HAL_DEBUG
                    /* Enable these prints for debugging if needed. */
                    ALOGD("%s: ts  %" PRId64, __FUNCTION__,
                        cached_results[i].results[j].ts);
                    ALOGD("%s: SSID  %s ", __FUNCTION__,
                        cached_results[i].results[j].ssid);
                    ALOGD("%s: BSSID: " MACSTR " \n",
                        __FUNCTION__, MAC2STR(cached_results[i].results[j].bssid));
                    ALOGD("%s: channel %d ", __FUNCTION__,
                        cached_results[i].results[j].channel);
                    ALOGD("%s: rssi  %d ", __FUNCTION__,
                        cached_results[i].results[j].rssi);
                    ALOGD("%s: rtt  %" PRId64, __FUNCTION__,
                        cached_results[i].results[j].rtt);
                    ALOGD("%s: rtt_sd  %" PRId64, __FUNCTION__,
                        cached_results[i].results[j].rtt_sd);
#endif
                    /* Increment loop index for next record */
                    j++;
                    /* For this scan id, update the wifiScanResultsStartingIndex
                    * and number of cached results parsed so far.
                    */
                    mGetCachedResultsRspParams->wifiScanResultsStartingIndex = j;
                    cached_results[i].num_results++;
                } else {
                    /* We already parsed and stored up to max wifi_scan_results
                     * specified by the caller. Now, continue to loop over NL
                     * entries in order to properly update NL parsing pointer
                     * so it points to the next scan_id results.
                     */
                    ALOGD("%s: loop index:%d > max num"
                        " of wifi_scan_results:%d for gscan cached results"
                        " bucket:%d. Dummy loop", __FUNCTION__,
                        j, MAX_AP_CACHE_PER_SCAN, i);
                }
           }
           ALOGV("%s: cached_results[%d].num_results: %d ", __FUNCTION__,
            i, cached_results[i].num_results);
           /* Increment loop index for next cached scan result record */
           i++;
       }
       /* Increment starting index of filling cached results received */
       if (mGetCachedResultsRspParams->num_cached_results <= 1024)
           mGetCachedResultsRspParams->cachedResultsStartingIndex =
               mGetCachedResultsRspParams->num_cached_results - 1;
    return WIFI_SUCCESS;
}

/* Set the GSCAN BSSID Hotlist. */
wifi_error wifi_set_epno_list(wifi_request_id id,
                                wifi_interface_handle iface,
                                const wifi_epno_params *epno_params,
                                wifi_epno_handler handler)
{
    int i, num_networks;
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData, *nlPnoParamList;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanSetPnoListCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanSetPnoListCmdEventHandler =
        event_handlers->gScanSetPnoListCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
        ALOGE("%s: Enhanced PNO is not supported by the driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO
     * list was made earlier. If wifi_set_epno_list() is called while
     * another one is running, the request will be sent down to driver and
     * firmware. If the new request is successfully honored, then Wi-Fi HAL
     * will use the new request id for the gScanSetPnoListCmdEventHandler
     * object.
     */

    gScanCommand =
        new GScanCommand(
                    wifiHandle,
                    id,
                    OUI_QCA,
                    QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

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

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData) {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
            __FUNCTION__, ret);
        goto cleanup;
    }

    num_networks = (unsigned int)epno_params->num_networks > MAX_EPNO_NETWORKS ?
                   MAX_EPNO_NETWORKS : epno_params->num_networks;
    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI,
            epno_params->min5GHz_rssi) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI,
            epno_params->min24GHz_rssi) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX,
            epno_params->initial_score_max) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS,
            epno_params->current_connection_bonus) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS,
            epno_params->same_network_bonus) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS,
            epno_params->secure_bonus) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS,
            epno_params->band5GHz_bonus) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS,
            num_networks))
    {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add vendor atributes. Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlPnoParamList =
        gScanCommand->attr_start(
                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST);
    if (!nlPnoParamList) {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add attr. PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST. "
            "Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    /* Add nested NL attributes for ePno List. */
    for (i = 0; i < num_networks; i++) {
        wifi_epno_network pnoNetwork = epno_params->networks[i];
        struct nlattr *nlPnoNetwork = gScanCommand->attr_start(i);
        if (!nlPnoNetwork) {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Failed attr_start for nlPnoNetwork. Error:%d",
                __FUNCTION__, ret);
            goto cleanup;
        }
        if (gScanCommand->put_string(
                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID,
                pnoNetwork.ssid) ||
            gScanCommand->put_u8(
                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS,
                pnoNetwork.flags) ||
            gScanCommand->put_u8(
                QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT,
                pnoNetwork.auth_bit_field))
        {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Failed to add PNO_SET_LIST_PARAM_EPNO_NETWORK_*. "
                "Error:%d", __FUNCTION__, ret);
            goto cleanup;
        }
        gScanCommand->attr_end(nlPnoNetwork);
    }

    gScanCommand->attr_end(nlPnoParamList);

    gScanCommand->attr_end(nlData);

    GScanCallbackHandler callbackHandler;
    memset(&callbackHandler, 0, sizeof(callbackHandler));
    callbackHandler.on_pno_network_found = handler.on_network_found;

    /* Create an object of the event handler class to take care of the
      * asychronous events on the north-bound.
      */
    if (gScanSetPnoListCmdEventHandler == NULL) {
        gScanSetPnoListCmdEventHandler = new GScanCommandEventHandler(
                            wifiHandle,
                            id,
                            OUI_QCA,
                            QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST,
                            callbackHandler);
        if (gScanSetPnoListCmdEventHandler == NULL) {
            ALOGE("%s: Error instantiating "
                "gScanSetPnoListCmdEventHandler.", __FUNCTION__);
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        event_handlers->gScanSetPnoListCmdEventHandler =
            gScanSetPnoListCmdEventHandler;
    } else {
        gScanSetPnoListCmdEventHandler->setCallbackHandler(callbackHandler);
    }

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanSetPnoListCmdEventHandler != NULL) {
        gScanSetPnoListCmdEventHandler->set_request_id(id);
        gScanSetPnoListCmdEventHandler->enableEventHandling();
    }

cleanup:
    delete gScanCommand;
    /* Disable Event Handling if ret != 0 */
    if ((ret != WIFI_SUCCESS) && gScanSetPnoListCmdEventHandler) {
        ALOGI("%s: Error ret:%d, disable event handling",
            __FUNCTION__, ret);
        gScanSetPnoListCmdEventHandler->disableEventHandling();
    }
    return ret;
}

/* Reset the ePNO list - no ePNO networks should be matched after this */
wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface)
{
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);

    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
        ALOGE("%s: Enhanced PNO is not supported by the driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    gScanCommand = new GScanCommand(wifiHandle,
                                    id,
                                    OUI_QCA,
                                    QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

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

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData) {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
            __FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS,
            EPNO_NO_NETWORKS))
    {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add vendor atributes Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    gScanCommand->attr_end(nlData);

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);

cleanup:
    delete gScanCommand;
    return ret;
}

/* Set the ePNO Passpoint List. */
wifi_error wifi_set_passpoint_list(wifi_request_id id,
                                   wifi_interface_handle iface, int num,
                                   wifi_passpoint_network *networks,
                                   wifi_passpoint_event_handler handler)
{
    int i;
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData, *nlPasspointNetworksParamList;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanPnoSetPasspointListCmdEventHandler =
        event_handlers->gScanPnoSetPasspointListCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
        ALOGE("%s: Enhanced PNO is not supported by the driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO
     * passpoint list was made earlier. If wifi_set_passpoint_list() is called
     * while another one is running, the request will be sent down to driver and
     * firmware. If the new request is successfully honored, then Wi-Fi HAL
     * will use the new request id for the
     * gScanPnoSetPasspointListCmdEventHandler object.
     */
    gScanCommand =
        new GScanCommand(
                    wifiHandle,
                    id,
                    OUI_QCA,
                    QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST);
    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

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

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData) {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
            __FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
            id) ||
        gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM,
            num))
    {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add vendor atributes. Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    /* Add the vendor specific attributes for the NL command. */
    nlPasspointNetworksParamList =
        gScanCommand->attr_start(
            QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY);
    if (!nlPasspointNetworksParamList) {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed attr_start for PASSPOINT_LIST_PARAM_NETWORK_ARRAY. "
            "Error:%d", __FUNCTION__, ret);
        goto cleanup;
    }

    /* Add nested NL attributes for Passpoint List param. */
    for (i = 0; i < num; i++) {
        wifi_passpoint_network passpointNetwork = networks[i];
        struct nlattr *nlPasspointNetworkParam = gScanCommand->attr_start(i);
        if (!nlPasspointNetworkParam) {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Failed attr_start for nlPasspointNetworkParam. "
                "Error:%d", __FUNCTION__, ret);
            goto cleanup;
        }
        if (gScanCommand->put_u32(
                QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID,
                passpointNetwork.id) ||
            gScanCommand->put_string(
                QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM,
                passpointNetwork.realm) ||
            gScanCommand->put_bytes(
         QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID,
                (char*)passpointNetwork.roamingConsortiumIds,
                16 * sizeof(int64_t)) ||
            gScanCommand->put_bytes(
            QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN,
                (char*)passpointNetwork.plmn, 3 * sizeof(u8)))
        {
            ret = WIFI_ERROR_UNKNOWN;
            ALOGE("%s: Failed to add PNO_PASSPOINT_NETWORK_PARAM_ROAM_* attr. "
                "Error:%d", __FUNCTION__, ret);
            goto cleanup;
        }
        gScanCommand->attr_end(nlPasspointNetworkParam);
    }

    gScanCommand->attr_end(nlPasspointNetworksParamList);

    gScanCommand->attr_end(nlData);

    GScanCallbackHandler callbackHandler;
    memset(&callbackHandler, 0, sizeof(callbackHandler));
    callbackHandler.on_passpoint_network_found =
                        handler.on_passpoint_network_found;

    /* Create an object of the event handler class to take care of the
      * asychronous events on the north-bound.
      */
    if (gScanPnoSetPasspointListCmdEventHandler == NULL) {
        gScanPnoSetPasspointListCmdEventHandler = new GScanCommandEventHandler(
                        wifiHandle,
                        id,
                        OUI_QCA,
                        QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST,
                        callbackHandler);
        if (gScanPnoSetPasspointListCmdEventHandler == NULL) {
            ALOGE("%s: Error instantiating "
                "gScanPnoSetPasspointListCmdEventHandler.", __FUNCTION__);
            ret = WIFI_ERROR_UNKNOWN;
            goto cleanup;
        }
        event_handlers->gScanPnoSetPasspointListCmdEventHandler =
            gScanPnoSetPasspointListCmdEventHandler;
    } else {
        gScanPnoSetPasspointListCmdEventHandler->setCallbackHandler(callbackHandler);
    }

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS) {
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);
        goto cleanup;
    }

    if (gScanPnoSetPasspointListCmdEventHandler != NULL) {
        gScanPnoSetPasspointListCmdEventHandler->set_request_id(id);
        gScanPnoSetPasspointListCmdEventHandler->enableEventHandling();
    }

cleanup:
    delete gScanCommand;
    /* Disable Event Handling if ret != 0 */
    if ((ret != WIFI_SUCCESS) && gScanPnoSetPasspointListCmdEventHandler) {
        ALOGI("%s: Error ret:%d, disable event handling",
            __FUNCTION__, ret);
        gScanPnoSetPasspointListCmdEventHandler->disableEventHandling();
    }
    return ret;
}

wifi_error wifi_reset_passpoint_list(wifi_request_id id,
                            wifi_interface_handle iface)
{
    wifi_error ret;
    GScanCommand *gScanCommand;
    struct nlattr *nlData;
    interface_info *ifaceInfo = getIfaceInfo(iface);
    wifi_handle wifiHandle = getWifiHandle(iface);
    hal_info *info = getHalInfo(wifiHandle);
    gscan_event_handlers* event_handlers;
    GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler;

    event_handlers = (gscan_event_handlers*)info->gscan_handlers;
    gScanPnoSetPasspointListCmdEventHandler =
        event_handlers->gScanPnoSetPasspointListCmdEventHandler;

    if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) {
        ALOGE("%s: Enhanced PNO is not supported by the driver",
            __FUNCTION__);
        return WIFI_ERROR_NOT_SUPPORTED;
    }

    if (gScanPnoSetPasspointListCmdEventHandler == NULL ||
        (gScanPnoSetPasspointListCmdEventHandler->isEventHandlingEnabled() ==
         false)) {
        ALOGE("wifi_reset_passpoint_list: ePNO passpoint_list isn't set. "
            "Nothing to do. Exit.");
        return WIFI_ERROR_NOT_AVAILABLE;
    }

    gScanCommand = new GScanCommand(
                    wifiHandle,
                    id,
                    OUI_QCA,
                    QCA_NL80211_VENDOR_SUBCMD_PNO_RESET_PASSPOINT_LIST);

    if (gScanCommand == NULL) {
        ALOGE("%s: Error GScanCommand NULL", __FUNCTION__);
        return WIFI_ERROR_UNKNOWN;
    }

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

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

    /* Add the vendor specific attributes for the NL command. */
    nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    if (!nlData) {
        ret = WIFI_ERROR_UNKNOWN;
        ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d",
            __FUNCTION__, ret);
        goto cleanup;
    }

    ret = gScanCommand->put_u32(
            QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
    if (ret != WIFI_SUCCESS) {
        ret = WIFI_ERROR_OUT_OF_MEMORY;
        ALOGE("%s: Failed to add vendor data attributes. Error:%d",
            __FUNCTION__, ret);
        goto cleanup;
    }

    gScanCommand->attr_end(nlData);

    ret = gScanCommand->requestResponse();
    if (ret != WIFI_SUCCESS)
        ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret);

    /* Disable Event Handling. */
    if (gScanPnoSetPasspointListCmdEventHandler) {
        gScanPnoSetPasspointListCmdEventHandler->disableEventHandling();
    }

cleanup:
    delete gScanCommand;
    return ret;
}

wifi_error GScanCommand::allocCachedResultsTemp(int max,
                                     wifi_cached_scan_results *cached_results)
{
    /* Alloc memory for "max" number of cached results. */
    mGetCachedResultsRspParams->cached_results =
        (wifi_cached_scan_results*)
        malloc(max * sizeof(wifi_cached_scan_results));
    if (!mGetCachedResultsRspParams->cached_results) {
        ALOGE("%s: Failed to allocate memory for "
              "mGetCachedResultsRspParams->cached_results.",
              __FUNCTION__);
        return WIFI_ERROR_OUT_OF_MEMORY;
    }
    memset(mGetCachedResultsRspParams->cached_results, 0,
           max * sizeof(wifi_cached_scan_results));

    mGetCachedResultsRspParams->max = max;

    return WIFI_SUCCESS;
}

/*
 * Allocates memory for the subCmd response struct and initializes status = -1
 */
wifi_error GScanCommand::allocRspParams(eGScanRspRarams cmd)
{
    switch(cmd)
    {
        case eGScanGetCachedResultsRspParams:
            mGetCachedResultsRspParams = (GScanGetCachedResultsRspParams *)
                malloc(sizeof(GScanGetCachedResultsRspParams));
            if (!mGetCachedResultsRspParams)
                return WIFI_ERROR_OUT_OF_MEMORY;

            mGetCachedResultsRspParams->num_cached_results = 0;
            mGetCachedResultsRspParams->more_data = false;
            mGetCachedResultsRspParams->cachedResultsStartingIndex = -1;
            mGetCachedResultsRspParams->lastProcessedScanId = -1;
            mGetCachedResultsRspParams->wifiScanResultsStartingIndex = -1;
            mGetCachedResultsRspParams->max = 0;
            mGetCachedResultsRspParams->cached_results = NULL;
        break;
        default:
            ALOGD("%s: Wrong request for alloc.", __FUNCTION__);
            return WIFI_ERROR_NOT_SUPPORTED;
    }
    return WIFI_SUCCESS;
}

void GScanCommand::freeRspParams(eGScanRspRarams cmd)
{
    switch(cmd)
    {
        case eGScanGetCachedResultsRspParams:
            if (mGetCachedResultsRspParams) {
                if (mGetCachedResultsRspParams->cached_results) {
                    free(mGetCachedResultsRspParams->cached_results);
                    mGetCachedResultsRspParams->cached_results = NULL;
                }
                free(mGetCachedResultsRspParams);
                mGetCachedResultsRspParams = NULL;
            }
        break;
        default:
            ALOGD("%s: Wrong request for free.", __FUNCTION__);
    }
}

wifi_error GScanCommand::copyCachedScanResults(
                                      int *numResults,
                                      wifi_cached_scan_results *cached_results)
{
    wifi_error ret = WIFI_ERROR_UNKNOWN;
    int i;
    wifi_cached_scan_results *cachedResultRsp;

    if (mGetCachedResultsRspParams && cached_results)
    {
        /* Populate the number of parsed cached results. */
        *numResults = mGetCachedResultsRspParams->num_cached_results;

        for (i = 0; i < *numResults; i++) {
            cachedResultRsp = &mGetCachedResultsRspParams->cached_results[i];
            cached_results[i].scan_id = cachedResultRsp->scan_id;
            cached_results[i].flags = cachedResultRsp->flags;
            cached_results[i].num_results = cachedResultRsp->num_results;
            cached_results[i].buckets_scanned = cachedResultRsp->buckets_scanned;

            if (!cached_results[i].num_results) {
                ALOGI("Error: cached_results[%d].num_results=0", i);
                continue;
            }

            ALOGV("copyCachedScanResults: "
                "cached_results[%d].num_results : %d",
                i, cached_results[i].num_results);

            memcpy(cached_results[i].results,
                cachedResultRsp->results,
                cached_results[i].num_results * sizeof(wifi_scan_result));
            ret = WIFI_SUCCESS;
        }
    } else {
        ALOGE("%s: mGetCachedResultsRspParams is NULL", __FUNCTION__);
        *numResults = 0;
        ret = WIFI_ERROR_INVALID_ARGS;
    }
    return ret;
}

void GScanCommand::setMaxChannels(int max_channels) {
    mMaxChannels = max_channels;
}

void GScanCommand::setChannels(int *channels) {
    mChannels = channels;
}

void GScanCommand::setNumChannelsPtr(int *num_channels) {
    mNumChannelsPtr = num_channels;
}
