Home | History | Annotate | Download | only in wifi_hal
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "sync.h"
     18 #define LOG_TAG  "WifiHAL"
     19 #include <utils/Log.h>
     20 #include <time.h>
     21 
     22 #include "common.h"
     23 #include "cpp_bindings.h"
     24 #include "gscancommand.h"
     25 #include "gscan_event_handler.h"
     26 
     27 #define GSCAN_EVENT_WAIT_TIME_SECONDS 4
     28 
     29 /* Used to handle gscan command events from driver/firmware. */
     30 GScanCommandEventHandler *GScanStartCmdEventHandler = NULL;
     31 GScanCommandEventHandler *GScanSetBssidHotlistCmdEventHandler = NULL;
     32 GScanCommandEventHandler *GScanSetSignificantChangeCmdEventHandler = NULL;
     33 
     34 /* Implementation of the API functions exposed in gscan.h */
     35 wifi_error wifi_get_valid_channels(wifi_interface_handle handle,
     36        int band, int max_channels, wifi_channel *channels, int *num_channels)
     37 {
     38     int requestId, ret = 0;
     39     GScanCommand *gScanCommand;
     40     struct nlattr *nlData;
     41     interface_info *ifaceInfo = getIfaceInfo(handle);
     42     wifi_handle wifiHandle = getWifiHandle(handle);
     43 
     44     if (channels == NULL) {
     45         ALOGE("%s: NULL channels pointer provided. Exit.",
     46             __func__);
     47         return WIFI_ERROR_INVALID_ARGS;
     48     }
     49 
     50     /* No request id from caller, so generate one and pass it on to the driver.
     51      * Generate one randomly.
     52      */
     53     srand( time(NULL) );
     54     requestId = rand();
     55 
     56     gScanCommand = new GScanCommand(
     57                             wifiHandle,
     58                             requestId,
     59                             OUI_QCA,
     60                             QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS);
     61     if (gScanCommand == NULL) {
     62         ALOGE("%s: Error GScanCommand NULL", __func__);
     63         return WIFI_ERROR_UNKNOWN;
     64     }
     65     /* Create the NL message. */
     66     ret = gScanCommand->create();
     67     if (ret < 0)
     68         goto cleanup;
     69 
     70     /* Set the interface Id of the message. */
     71     ret = gScanCommand->set_iface_id(ifaceInfo->name);
     72     if (ret < 0)
     73         goto cleanup;
     74 
     75     /* Add the vendor specific attributes for the NL command. */
     76     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
     77     if (!nlData)
     78         goto cleanup;
     79 
     80     if (gScanCommand->put_u32(
     81             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
     82             requestId) ||
     83         gScanCommand->put_u32(
     84         QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND,
     85             band) ||
     86         gScanCommand->put_u32(
     87         QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS,
     88             max_channels) )
     89     {
     90         goto cleanup;
     91     }
     92     gScanCommand->attr_end(nlData);
     93     /* Populate the input received from caller/framework. */
     94     gScanCommand->setMaxChannels(max_channels);
     95     gScanCommand->setChannels(channels);
     96     gScanCommand->setNumChannelsPtr(num_channels);
     97 
     98     /* Send the msg and wait for a response. */
     99     ret = gScanCommand->requestResponse();
    100     if (ret) {
    101         ALOGE("%s: Error %d happened. ", __func__, ret);
    102     }
    103 
    104 cleanup:
    105     ALOGI("%s: Delete object.", __func__);
    106     delete gScanCommand;
    107     return (wifi_error)ret;
    108 }
    109 
    110 void get_gscan_capabilities_cb(int status, wifi_gscan_capabilities capa)
    111 {
    112     ALOGD("%s: Status = %d.", __func__, status);
    113     ALOGD("%s: Capabilities. max_ap_cache_per_scan:%d, "
    114             "max_bssid_history_entries:%d, max_hotlist_aps:%d, "
    115             "max_rssi_sample_size:%d, max_scan_buckets:%d, "
    116             "max_scan_cache_size:%d, max_scan_reporting_threshold:%d, "
    117             "max_significant_wifi_change_aps:%d.",
    118             __func__, capa.max_ap_cache_per_scan,
    119             capa.max_bssid_history_entries,
    120             capa.max_hotlist_aps, capa.max_rssi_sample_size,
    121             capa.max_scan_buckets,
    122             capa.max_scan_cache_size, capa.max_scan_reporting_threshold,
    123             capa.max_significant_wifi_change_aps);
    124 }
    125 
    126 wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
    127                                  wifi_gscan_capabilities *capabilities)
    128 {
    129     int requestId, ret = 0;
    130     GScanCommand *gScanCommand;
    131     struct nlattr *nlData;
    132     wifi_gscan_capabilities tCapabilities;
    133     interface_info *ifaceInfo = getIfaceInfo(handle);
    134     wifi_handle wifiHandle = getWifiHandle(handle);
    135 
    136     if (capabilities == NULL) {
    137         ALOGE("%s: NULL capabilities pointer provided. Exit.",
    138             __func__);
    139         return WIFI_ERROR_INVALID_ARGS;
    140     }
    141 
    142     /* No request id from caller, so generate one and pass it on to the driver.
    143      * Generate it randomly.
    144      */
    145     srand(time(NULL));
    146     requestId = rand();
    147 
    148     gScanCommand = new GScanCommand(
    149                             wifiHandle,
    150                             requestId,
    151                             OUI_QCA,
    152                             QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES);
    153     if (gScanCommand == NULL) {
    154         ALOGE("%s: Error GScanCommand NULL", __func__);
    155         return WIFI_ERROR_UNKNOWN;
    156     }
    157 
    158     GScanCallbackHandler callbackHandler;
    159     memset(&callbackHandler, 0, sizeof(callbackHandler));
    160     callbackHandler.get_capabilities = get_gscan_capabilities_cb;
    161 
    162     ret = gScanCommand->setCallbackHandler(callbackHandler);
    163     if (ret < 0)
    164         goto cleanup;
    165 
    166     /* Create the NL message. */
    167     ret = gScanCommand->create();
    168     if (ret < 0)
    169         goto cleanup;
    170 
    171     /* Set the interface Id of the message. */
    172     ret = gScanCommand->set_iface_id(ifaceInfo->name);
    173     if (ret < 0)
    174         goto cleanup;
    175 
    176     /* Add the vendor specific attributes for the NL command. */
    177     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    178     if (!nlData)
    179         goto cleanup;
    180 
    181     ret = gScanCommand->put_u32(
    182             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
    183             requestId);
    184     if (ret < 0)
    185         goto cleanup;
    186 
    187     gScanCommand->attr_end(nlData);
    188     ret = gScanCommand->allocRspParams(eGScanGetCapabilitiesRspParams);
    189     if (ret != 0) {
    190         ALOGE("%s: Failed to allocate memory fo response struct. Error:%d",
    191             __func__, ret);
    192         goto cleanup;
    193     }
    194 
    195     gScanCommand->waitForRsp(true);
    196     ret = gScanCommand->requestEvent();
    197     if (ret != 0) {
    198         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    199         goto cleanup;
    200     }
    201 
    202     gScanCommand->getGetCapabilitiesRspParams(capabilities, (u32 *)&ret);
    203 
    204 cleanup:
    205     gScanCommand->freeRspParams(eGScanGetCapabilitiesRspParams);
    206     ALOGI("%s: Delete object.", __func__);
    207     delete gScanCommand;
    208     return (wifi_error)ret;
    209 }
    210 
    211 void start_gscan_cb(int status)
    212 {
    213     ALOGD("%s: Status = %d.", __func__, status);
    214 }
    215 
    216 wifi_error wifi_start_gscan(wifi_request_id id,
    217                             wifi_interface_handle iface,
    218                             wifi_scan_cmd_params params,
    219                             wifi_scan_result_handler handler)
    220 {
    221     int ret = 0;
    222     u32 i, j;
    223     GScanCommand *gScanCommand;
    224     struct nlattr *nlData;
    225     interface_info *ifaceInfo = getIfaceInfo(iface);
    226     wifi_handle wifiHandle = getWifiHandle(iface);
    227     u32 num_scan_buckets, numChannelSpecs;
    228     wifi_scan_bucket_spec bucketSpec;
    229     struct nlattr *nlBuckectSpecList;
    230 
    231     /* Check if a similar request to start gscan was made earlier.
    232      * Right now we don't differentiate between the case where (i) the new
    233      * Request Id is different from the current one vs (ii) case where both
    234      * new and Request IDs are the same.
    235      */
    236     if (GScanStartCmdEventHandler) {
    237         if (id == GScanStartCmdEventHandler->get_request_id()) {
    238             ALOGE("wifi_start_gscan(): GSCAN Start for request Id %d is still "
    239                  "running. Exit", id);
    240             return WIFI_ERROR_TOO_MANY_REQUESTS;
    241         } else {
    242             ALOGE("wifi_start_gscan(): GSCAN Start for a different request "
    243                 "Id %d is requested. Not supported. Exit", id);
    244             return WIFI_ERROR_NOT_SUPPORTED;
    245         }
    246     }
    247 
    248     gScanCommand = new GScanCommand(
    249                                 wifiHandle,
    250                                 id,
    251                                 OUI_QCA,
    252                                 QCA_NL80211_VENDOR_SUBCMD_GSCAN_START);
    253     if (gScanCommand == NULL) {
    254         ALOGE("wifi_start_gscan(): Error GScanCommand NULL");
    255         return WIFI_ERROR_UNKNOWN;
    256     }
    257 
    258     GScanCallbackHandler callbackHandler;
    259     memset(&callbackHandler, 0, sizeof(callbackHandler));
    260     callbackHandler.start = start_gscan_cb;
    261 
    262     ret = gScanCommand->setCallbackHandler(callbackHandler);
    263     if (ret < 0)
    264         goto cleanup;
    265 
    266     /* Create the NL message. */
    267     ret = gScanCommand->create();
    268     if (ret < 0)
    269         goto cleanup;
    270 
    271     /* Set the interface Id of the message. */
    272     ret = gScanCommand->set_iface_id(ifaceInfo->name);
    273     if (ret < 0)
    274         goto cleanup;
    275 
    276     /* Add the vendor specific attributes for the NL command. */
    277     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    278     if (!nlData)
    279         goto cleanup;
    280 
    281     num_scan_buckets = (unsigned int)params.num_buckets > MAX_BUCKETS ?
    282                             MAX_BUCKETS : params.num_buckets;
    283 
    284     if (gScanCommand->put_u32(
    285             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
    286             id) ||
    287         gScanCommand->put_u32(
    288             QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD,
    289             params.base_period) ||
    290         gScanCommand->put_u32(
    291             QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN,
    292             params.max_ap_per_scan) ||
    293         gScanCommand->put_u8(
    294             QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD,
    295             params.report_threshold) ||
    296         gScanCommand->put_u8(
    297             QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS,
    298             num_scan_buckets))
    299     {
    300         goto cleanup;
    301     }
    302 
    303     nlBuckectSpecList =
    304         gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC);
    305     /* Add NL attributes for scan bucket specs . */
    306     for (i = 0; i < num_scan_buckets; i++) {
    307         bucketSpec = params.buckets[i];
    308         numChannelSpecs = (unsigned int)bucketSpec.num_channels > MAX_CHANNELS ?
    309                                 MAX_CHANNELS : bucketSpec.num_channels;
    310         struct nlattr *nlBucketSpec = gScanCommand->attr_start(i);
    311         if (gScanCommand->put_u8(
    312                 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX,
    313                 bucketSpec.bucket) ||
    314             gScanCommand->put_u8(
    315                 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND,
    316                 bucketSpec.band) ||
    317             gScanCommand->put_u32(
    318                 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD,
    319                 bucketSpec.period) ||
    320             gScanCommand->put_u8(
    321                 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS,
    322                 bucketSpec.report_events) ||
    323             gScanCommand->put_u32(
    324                 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS,
    325                 numChannelSpecs))
    326         {
    327             goto cleanup;
    328         }
    329 
    330         struct nlattr *nl_channelSpecList =
    331             gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC);
    332 
    333         /* Add NL attributes for scan channel specs . */
    334         for (j = 0; j < numChannelSpecs; j++) {
    335             struct nlattr *nl_channelSpec = gScanCommand->attr_start(j);
    336             wifi_scan_channel_spec channel_spec = bucketSpec.channels[j];
    337 
    338             if ( gScanCommand->put_u32(
    339                     QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL,
    340                     channel_spec.channel) ||
    341                 gScanCommand->put_u32(
    342                     QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME,
    343                     channel_spec.dwellTimeMs) ||
    344                 gScanCommand->put_u8(
    345                     QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE,
    346                     channel_spec.passive) )
    347             {
    348                 goto cleanup;
    349             }
    350 
    351             gScanCommand->attr_end(nl_channelSpec);
    352         }
    353         gScanCommand->attr_end(nl_channelSpecList);
    354         gScanCommand->attr_end(nlBucketSpec);
    355     }
    356     gScanCommand->attr_end(nlBuckectSpecList);
    357 
    358     gScanCommand->attr_end(nlData);
    359 
    360     ret = gScanCommand->allocRspParams(eGScanStartRspParams);
    361     if (ret != 0) {
    362         ALOGE("wifi_start_gscan(): Failed to allocate memory to the response "
    363             "struct. Error:%d", ret);
    364         goto cleanup;
    365     }
    366 
    367     /* Set the callback handler functions for related events. */
    368     callbackHandler.on_scan_results_available =
    369                         handler.on_scan_results_available;
    370     callbackHandler.on_full_scan_result = handler.on_full_scan_result;
    371     callbackHandler.on_scan_event = handler.on_scan_event;
    372     /* Create an object to handle the related events from firmware/driver. */
    373     GScanStartCmdEventHandler = new GScanCommandEventHandler(
    374                                 wifiHandle,
    375                                 id,
    376                                 OUI_QCA,
    377                                 QCA_NL80211_VENDOR_SUBCMD_GSCAN_START,
    378                                 callbackHandler);
    379     if (GScanStartCmdEventHandler == NULL) {
    380         ALOGE("wifi_start_gscan(): Error GScanStartCmdEventHandler NULL");
    381         ret = WIFI_ERROR_UNKNOWN;
    382         goto cleanup;
    383     }
    384 
    385     gScanCommand->waitForRsp(true);
    386     ret = gScanCommand->requestEvent();
    387     if (ret != 0) {
    388         ALOGE("wifi_start_gscan(): requestEvent Error:%d", ret);
    389         goto cleanup;
    390     }
    391 
    392     gScanCommand->getStartGScanRspParams((u32 *)&ret);
    393     if (ret != 0)
    394     {
    395         goto cleanup;
    396     }
    397 
    398 cleanup:
    399     gScanCommand->freeRspParams(eGScanStartRspParams);
    400     ALOGI("wifi_start_gscan(): Delete object.");
    401     delete gScanCommand;
    402     /* Delete the command event handler object if ret != 0 */
    403     if (ret && GScanStartCmdEventHandler) {
    404         ALOGI("wifi_start_gscan(): Error ret:%d, delete event handler object.",
    405             ret);
    406         delete GScanStartCmdEventHandler;
    407         GScanStartCmdEventHandler = NULL;
    408     }
    409     return (wifi_error)ret;
    410 
    411 }
    412 
    413 void stop_gscan_cb(int status)
    414 {
    415     ALOGD("%s: Status = %d.", __func__, status);
    416 }
    417 
    418 wifi_error wifi_stop_gscan(wifi_request_id id,
    419                             wifi_interface_handle iface)
    420 {
    421     int ret = 0;
    422     GScanCommand *gScanCommand;
    423     struct nlattr *nlData;
    424 
    425     interface_info *ifaceInfo = getIfaceInfo(iface);
    426     wifi_handle wifiHandle = getWifiHandle(iface);
    427 
    428     ALOGI("Stopping GScan, halHandle = %p", wifiHandle);
    429 
    430     if (GScanStartCmdEventHandler) {
    431         if (id != GScanStartCmdEventHandler->get_request_id()) {
    432             ALOGE("wifi_stop_gscan: GSCAN Stop requested for request Id %d "
    433                 "not matching that of existing GScan Start:%d. Exit",
    434                 id, GScanStartCmdEventHandler->get_request_id());
    435             return WIFI_ERROR_INVALID_REQUEST_ID;
    436         }
    437     } else {
    438         ALOGE("wifi_stop_gscan: GSCAN isn't running or already stopped. "
    439             "Nothing to do. Exit");
    440         return WIFI_ERROR_NOT_AVAILABLE;
    441     }
    442 
    443     gScanCommand = new GScanCommand(
    444                                 wifiHandle,
    445                                 id,
    446                                 OUI_QCA,
    447                                 QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP);
    448     if (gScanCommand == NULL) {
    449         ALOGE("%s: Error GScanCommand NULL", __func__);
    450         return WIFI_ERROR_UNKNOWN;
    451     }
    452 
    453     GScanCallbackHandler callbackHandler;
    454     memset(&callbackHandler, 0, sizeof(callbackHandler));
    455     callbackHandler.stop = stop_gscan_cb;
    456 
    457     ret = gScanCommand->setCallbackHandler(callbackHandler);
    458     if (ret < 0)
    459         goto cleanup;
    460 
    461     /* Create the NL message. */
    462     ret = gScanCommand->create();
    463     if (ret < 0)
    464         goto cleanup;
    465 
    466     /* Set the interface Id of the message. */
    467     ret = gScanCommand->set_iface_id(ifaceInfo->name);
    468     if (ret < 0)
    469         goto cleanup;
    470 
    471     /* Add the vendor specific attributes for the NL command. */
    472     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    473     if (!nlData)
    474         goto cleanup;
    475 
    476     ret = gScanCommand->put_u32(
    477             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
    478             id);
    479     if (ret < 0)
    480         goto cleanup;
    481 
    482     gScanCommand->attr_end(nlData);
    483 
    484     ret = gScanCommand->allocRspParams(eGScanStopRspParams);
    485     if (ret != 0) {
    486         ALOGE("%s: Failed to allocate memory to the response struct. "
    487             "Error:%d", __func__, ret);
    488         goto cleanup;
    489     }
    490 
    491     gScanCommand->waitForRsp(true);
    492     ret = gScanCommand->requestEvent();
    493     if (ret != 0) {
    494         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    495         goto cleanup;
    496     }
    497 
    498     gScanCommand->getStopGScanRspParams((u32 *)&ret);
    499     if (ret != 0)
    500     {
    501         goto cleanup;
    502     }
    503 
    504     /* Delete different GSCAN event handlers for the specified Request ID. */
    505     if (GScanStartCmdEventHandler) {
    506         delete GScanStartCmdEventHandler;
    507         GScanStartCmdEventHandler = NULL;
    508     }
    509 
    510 cleanup:
    511     gScanCommand->freeRspParams(eGScanStopRspParams);
    512     ALOGI("%s: Delete object.", __func__);
    513     delete gScanCommand;
    514     return (wifi_error)ret;
    515 }
    516 
    517 void set_bssid_hotlist_cb(int status)
    518 {
    519     ALOGD("%s: Status = %d.", __func__, status);
    520 }
    521 
    522 /* Set the GSCAN BSSID Hotlist. */
    523 wifi_error wifi_set_bssid_hotlist(wifi_request_id id,
    524                                     wifi_interface_handle iface,
    525                                     wifi_bssid_hotlist_params params,
    526                                     wifi_hotlist_ap_found_handler handler)
    527 {
    528     int i, numAp, ret = 0;
    529     GScanCommand *gScanCommand;
    530     struct nlattr *nlData, *nlApThresholdParamList;
    531     interface_info *ifaceInfo = getIfaceInfo(iface);
    532     wifi_handle wifiHandle = getWifiHandle(iface);
    533 
    534     ALOGD("Setting GScan BSSID Hotlist, halHandle = %p", wifiHandle);
    535 
    536     /* Check if a similar request to set bssid hotlist was made earlier.
    537      * Right now we don't differentiate between the case where (i) the new
    538      * Request Id is different from the current one vs (ii) case where both
    539      * new and Request IDs are the same.
    540      */
    541     if (GScanSetBssidHotlistCmdEventHandler)
    542         if (id == GScanSetBssidHotlistCmdEventHandler->get_request_id()) {
    543             ALOGE("%s: GSCAN Set BSSID Hotlist for request Id %d is still"
    544                 "running. Exit", __func__, id);
    545             return WIFI_ERROR_TOO_MANY_REQUESTS;
    546         } else {
    547             ALOGD("%s: GSCAN Set BSSID Hotlist for a different Request Id:%d"
    548                 "is requested. Not supported. Exit", __func__, id);
    549             return WIFI_ERROR_NOT_SUPPORTED;
    550         }
    551 
    552     gScanCommand =
    553         new GScanCommand(
    554                     wifiHandle,
    555                     id,
    556                     OUI_QCA,
    557                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST);
    558     if (gScanCommand == NULL) {
    559         ALOGE("%s: Error GScanCommand NULL", __func__);
    560         return WIFI_ERROR_UNKNOWN;
    561     }
    562 
    563     GScanCallbackHandler callbackHandler;
    564     memset(&callbackHandler, 0, sizeof(callbackHandler));
    565     callbackHandler.set_bssid_hotlist = set_bssid_hotlist_cb,
    566 
    567     ret = gScanCommand->setCallbackHandler(callbackHandler);
    568     if (ret < 0)
    569         goto cleanup;
    570 
    571     /* Create the NL message. */
    572     ret = gScanCommand->create();
    573     if (ret < 0)
    574         goto cleanup;
    575 
    576     /* Set the interface Id of the message. */
    577     ret = gScanCommand->set_iface_id(ifaceInfo->name);
    578     if (ret < 0)
    579         goto cleanup;
    580 
    581     /* Add the vendor specific attributes for the NL command. */
    582     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    583     if (!nlData)
    584         goto cleanup;
    585 
    586     numAp = (unsigned int)params.num_ap > MAX_HOTLIST_APS ? MAX_HOTLIST_APS : params.num_ap;
    587     if (gScanCommand->put_u32(
    588             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
    589             id) ||
    590         gScanCommand->put_u32(
    591             QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP,
    592             numAp))
    593     {
    594         goto cleanup;
    595     }
    596 
    597     /* Add the vendor specific attributes for the NL command. */
    598     nlApThresholdParamList =
    599         gScanCommand->attr_start(
    600                                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM);
    601     if (!nlApThresholdParamList)
    602         goto cleanup;
    603 
    604     /* Add nested NL attributes for AP Threshold Param. */
    605     for (i = 0; i < numAp; i++) {
    606         ap_threshold_param apThreshold = params.ap[i];
    607         struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i);
    608         if (!nlApThresholdParam)
    609             goto cleanup;
    610         if (gScanCommand->put_addr(
    611                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID,
    612                 apThreshold.bssid) ||
    613             gScanCommand->put_s32(
    614                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW,
    615                 apThreshold.low) ||
    616             gScanCommand->put_s32(
    617                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH,
    618                 apThreshold.high) ||
    619             gScanCommand->put_u32(
    620                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_CHANNEL,
    621                 apThreshold.channel))
    622         {
    623             goto cleanup;
    624         }
    625         gScanCommand->attr_end(nlApThresholdParam);
    626     }
    627 
    628     gScanCommand->attr_end(nlApThresholdParamList);
    629 
    630     gScanCommand->attr_end(nlData);
    631 
    632     ret = gScanCommand->allocRspParams(eGScanSetBssidHotlistRspParams);
    633     if (ret != 0) {
    634         ALOGE("%s: Failed to allocate memory to the response struct. "
    635             "Error:%d", __func__, ret);
    636         goto cleanup;
    637     }
    638 
    639     callbackHandler.on_hotlist_ap_found = handler.on_hotlist_ap_found;
    640     /* Create an object of the event handler class to take care of the
    641       * asychronous events on the north-bound.
    642       */
    643     GScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler(
    644                             wifiHandle,
    645                             id,
    646                             OUI_QCA,
    647                             QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST,
    648                             callbackHandler);
    649     if (GScanSetBssidHotlistCmdEventHandler == NULL) {
    650         ALOGE("%s: Error instantiating GScanSetBssidHotlistCmdEventHandler.",
    651             __func__);
    652         ret = WIFI_ERROR_UNKNOWN;
    653         goto cleanup;
    654     }
    655 
    656     ALOGD("%s: Handler object was created for HOTLIST_AP_FOUND.", __func__);
    657 
    658     gScanCommand->waitForRsp(true);
    659     ret = gScanCommand->requestEvent();
    660     if (ret != 0) {
    661         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    662         goto cleanup;
    663     }
    664 
    665     gScanCommand->getSetBssidHotlistRspParams((u32 *)&ret);
    666     if (ret != 0)
    667     {
    668         goto cleanup;
    669     }
    670 
    671 cleanup:
    672     gScanCommand->freeRspParams(eGScanSetBssidHotlistRspParams);
    673     ALOGI("%s: Delete object. ", __func__);
    674     delete gScanCommand;
    675     /* Delete the command event handler object if ret != 0 */
    676     if (ret && GScanSetBssidHotlistCmdEventHandler) {
    677         delete GScanSetBssidHotlistCmdEventHandler;
    678         GScanSetBssidHotlistCmdEventHandler = NULL;
    679     }
    680     return (wifi_error)ret;
    681 }
    682 
    683 void reset_bssid_hotlist_cb(int status)
    684 {
    685     ALOGD("%s: Status = %d.", __func__, status);
    686 }
    687 
    688 wifi_error wifi_reset_bssid_hotlist(wifi_request_id id,
    689                             wifi_interface_handle iface)
    690 {
    691     int ret = 0;
    692     GScanCommand *gScanCommand;
    693     struct nlattr *nlData;
    694     interface_info *ifaceInfo = getIfaceInfo(iface);
    695     wifi_handle wifiHandle = getWifiHandle(iface);
    696 
    697     ALOGE("Resetting GScan BSSID Hotlist, halHandle = %p", wifiHandle);
    698 
    699     if (GScanSetBssidHotlistCmdEventHandler) {
    700         if (id != GScanSetBssidHotlistCmdEventHandler->get_request_id()) {
    701             ALOGE("%s: GSCAN Reset Hotlist BSSID requested for request Id %d"
    702                 "not matching that of existing GScan Set Hotlist BSSID:%d. "
    703                 "Exit", __func__, id,
    704                 GScanSetBssidHotlistCmdEventHandler->get_request_id());
    705             return WIFI_ERROR_INVALID_REQUEST_ID;
    706         }
    707     }
    708 
    709     gScanCommand = new GScanCommand(
    710                         wifiHandle,
    711                         id,
    712                         OUI_QCA,
    713                         QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST);
    714 
    715     if (gScanCommand == NULL) {
    716         ALOGE("%s: Error GScanCommand NULL", __func__);
    717         return WIFI_ERROR_UNKNOWN;
    718     }
    719 
    720     GScanCallbackHandler callbackHandler;
    721     memset(&callbackHandler, 0, sizeof(callbackHandler));
    722     callbackHandler.reset_bssid_hotlist = reset_bssid_hotlist_cb;
    723 
    724     ret = gScanCommand->setCallbackHandler(callbackHandler);
    725     if (ret < 0)
    726         goto cleanup;
    727 
    728     /* Create the NL message. */
    729     ret = gScanCommand->create();
    730     if (ret < 0)
    731         goto cleanup;
    732 
    733     /* Set the interface Id of the message. */
    734     ret = gScanCommand->set_iface_id(ifaceInfo->name);
    735     if (ret < 0)
    736         goto cleanup;
    737 
    738     /* Add the vendor specific attributes for the NL command. */
    739     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    740     if (!nlData)
    741         goto cleanup;
    742 
    743     ret = gScanCommand->put_u32(
    744             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id);
    745     if (ret < 0)
    746         goto cleanup;
    747 
    748     gScanCommand->attr_end(nlData);
    749 
    750     ret = gScanCommand->allocRspParams(eGScanResetBssidHotlistRspParams);
    751     if (ret != 0) {
    752         ALOGE("%s: Failed to allocate memory to the response struct. "
    753             "Error:%d", __func__, ret);
    754         goto cleanup;
    755     }
    756 
    757     gScanCommand->waitForRsp(true);
    758     ret = gScanCommand->requestEvent();
    759     if (ret != 0) {
    760         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    761         goto cleanup;
    762     }
    763 
    764     gScanCommand->getResetBssidHotlistRspParams((u32 *)&ret);
    765     if (ret != 0)
    766     {
    767         goto cleanup;
    768     }
    769 
    770     if (GScanSetBssidHotlistCmdEventHandler) {
    771         delete GScanSetBssidHotlistCmdEventHandler;
    772         GScanSetBssidHotlistCmdEventHandler = NULL;
    773     }
    774 
    775 cleanup:
    776     gScanCommand->freeRspParams(eGScanResetBssidHotlistRspParams);
    777     ALOGI("%s: Delete object.", __func__);
    778     delete gScanCommand;
    779     return (wifi_error)ret;
    780 }
    781 
    782 void set_significant_change_cb(int status)
    783 {
    784     ALOGD("%s: Status = %d.", __func__, status);
    785 }
    786 
    787 /* Set the GSCAN Significant AP Change list. */
    788 wifi_error wifi_set_significant_change_handler(wifi_request_id id,
    789                                             wifi_interface_handle iface,
    790                                     wifi_significant_change_params params,
    791                                     wifi_significant_change_handler handler)
    792 {
    793     int i, numAp, ret = 0;
    794     GScanCommand *gScanCommand;
    795     struct nlattr *nlData, *nlApThresholdParamList;
    796     interface_info *ifaceInfo = getIfaceInfo(iface);
    797     wifi_handle wifiHandle = getWifiHandle(iface);
    798 
    799     ALOGE("Setting GScan Significant Change, halHandle = %p", wifiHandle);
    800 
    801     /* Check if a similar request to set significant change was made earlier.
    802      * Right now we don't differentiate between the case where (i) the new
    803      * Request Id is different from the current one vs (ii) both new and
    804      * Request Ids are the same.
    805      */
    806     if (GScanSetSignificantChangeCmdEventHandler)
    807         if (id == GScanSetSignificantChangeCmdEventHandler->get_request_id()) {
    808             ALOGE("%s: GSCAN Set Significant Change for request Id %d is still"
    809                 "running. Exit", __func__, id);
    810             return WIFI_ERROR_TOO_MANY_REQUESTS;
    811         } else {
    812             ALOGE("%s: GSCAN Set Significant Change for a different Request "
    813                 "Id:%d is requested. Not supported. Exit", __func__, id);
    814             return WIFI_ERROR_NOT_SUPPORTED;
    815         }
    816 
    817     gScanCommand = new GScanCommand(
    818                     wifiHandle,
    819                     id,
    820                     OUI_QCA,
    821                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE);
    822     if (gScanCommand == NULL) {
    823         ALOGE("%s: Error GScanCommand NULL", __func__);
    824         return WIFI_ERROR_UNKNOWN;
    825     }
    826 
    827     GScanCallbackHandler callbackHandler;
    828     memset(&callbackHandler, 0, sizeof(callbackHandler));
    829     callbackHandler.set_significant_change = set_significant_change_cb;
    830 
    831     ret = gScanCommand->setCallbackHandler(callbackHandler);
    832     if (ret < 0)
    833         goto cleanup;
    834 
    835     /* Create the NL message. */
    836     ret = gScanCommand->create();
    837     if (ret < 0)
    838         goto cleanup;
    839 
    840     /* Set the interface Id of the message. */
    841     ret = gScanCommand->set_iface_id(ifaceInfo->name);
    842     if (ret < 0)
    843         goto cleanup;
    844 
    845     /* Add the vendor specific attributes for the NL command. */
    846     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
    847     if (!nlData)
    848         goto cleanup;
    849 
    850     numAp = (unsigned int)params.num_ap > MAX_SIGNIFICANT_CHANGE_APS ?
    851         MAX_SIGNIFICANT_CHANGE_APS : params.num_ap;
    852 
    853     if (gScanCommand->put_u32(
    854             QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
    855             id) ||
    856         gScanCommand->put_u32(
    857         QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE,
    858             params.rssi_sample_size) ||
    859         gScanCommand->put_u32(
    860         QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE,
    861             params.lost_ap_sample_size) ||
    862         gScanCommand->put_u32(
    863             QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING,
    864             params.min_breaching) ||
    865         gScanCommand->put_u32(
    866             QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP,
    867             numAp))
    868     {
    869         goto cleanup;
    870     }
    871 
    872     /* Add the vendor specific attributes for the NL command. */
    873     nlApThresholdParamList =
    874         gScanCommand->attr_start(
    875                                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM);
    876     if (!nlApThresholdParamList)
    877         goto cleanup;
    878 
    879     /* Add nested NL attributes for AP Threshold Param list. */
    880     for (i = 0; i < numAp; i++) {
    881         ap_threshold_param apThreshold = params.ap[i];
    882         struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i);
    883         if (!nlApThresholdParam)
    884             goto cleanup;
    885         if ( gScanCommand->put_addr(
    886                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID,
    887                 apThreshold.bssid) ||
    888             gScanCommand->put_s32(
    889                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW,
    890                 apThreshold.low) ||
    891             gScanCommand->put_s32(
    892                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH,
    893                 apThreshold.high) ||
    894             gScanCommand->put_u32(
    895                 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_CHANNEL,
    896                 apThreshold.channel) )
    897         {
    898             goto cleanup;
    899         }
    900         gScanCommand->attr_end(nlApThresholdParam);
    901     }
    902 
    903     gScanCommand->attr_end(nlApThresholdParamList);
    904 
    905     gScanCommand->attr_end(nlData);
    906 
    907     ret = gScanCommand->allocRspParams(eGScanSetSignificantChangeRspParams);
    908     if (ret != 0) {
    909         ALOGE("%s: Failed to allocate memory to the response struct. "
    910             "Error:%d", __func__, ret);
    911         goto cleanup;
    912     }
    913 
    914     callbackHandler.on_significant_change = handler.on_significant_change;
    915     /* Create an object of the event handler class to take care of the
    916       * asychronous events on the north-bound.
    917       */
    918     GScanSetSignificantChangeCmdEventHandler = new GScanCommandEventHandler(
    919                      wifiHandle,
    920                      id,
    921                      OUI_QCA,
    922                      QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE,
    923                      callbackHandler);
    924     if (GScanSetSignificantChangeCmdEventHandler == NULL) {
    925         ALOGE("%s: Error in instantiating, "
    926             "GScanSetSignificantChangeCmdEventHandler.",
    927             __func__);
    928         ret = WIFI_ERROR_UNKNOWN;
    929         goto cleanup;
    930     }
    931 
    932     ALOGD("%s: Event handler object was created for SIGNIFICANT_CHANGE.",
    933             __func__);
    934 
    935     gScanCommand->waitForRsp(true);
    936     ret = gScanCommand->requestEvent();
    937     if (ret != 0) {
    938         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    939         goto cleanup;
    940     }
    941 
    942     gScanCommand->getSetSignificantChangeRspParams((u32 *)&ret);
    943     if (ret != 0)
    944     {
    945         goto cleanup;
    946     }
    947 
    948 cleanup:
    949     gScanCommand->freeRspParams(eGScanSetSignificantChangeRspParams);
    950     ALOGI("%s: Delete object.", __func__);
    951     /* Delete the command event handler object if ret != 0 */
    952     if (ret && GScanSetSignificantChangeCmdEventHandler) {
    953         delete GScanSetSignificantChangeCmdEventHandler;
    954         GScanSetSignificantChangeCmdEventHandler = NULL;
    955     }
    956     delete gScanCommand;
    957     return (wifi_error)ret;
    958 }
    959 
    960 void reset_significant_change_cb(int status)
    961 {
    962     ALOGD("%s: Status = %d.", __func__, status);
    963 }
    964 
    965 /* Clear the GSCAN Significant AP change list. */
    966 wifi_error wifi_reset_significant_change_handler(wifi_request_id id,
    967                                             wifi_interface_handle iface)
    968 {
    969     int ret = 0;
    970     GScanCommand *gScanCommand;
    971     struct nlattr *nlData;
    972     interface_info *ifaceInfo = getIfaceInfo(iface);
    973     wifi_handle wifiHandle = getWifiHandle(iface);
    974 
    975     ALOGD("Resetting GScan Significant Change, halHandle = %p", wifiHandle);
    976 
    977     if (GScanSetSignificantChangeCmdEventHandler) {
    978         if (id != GScanSetSignificantChangeCmdEventHandler->get_request_id()) {
    979             ALOGE("%s: GSCAN Reset Significant Change requested for request "
    980                 "Id %d not matching that of existing GScan Set Hotlist "
    981                 "BSSID:%d. Exit", __func__, id,
    982                 GScanSetSignificantChangeCmdEventHandler->get_request_id());
    983             return WIFI_ERROR_INVALID_REQUEST_ID;
    984         }
    985     }
    986 
    987     gScanCommand =
    988         new GScanCommand
    989                     (
    990                     wifiHandle,
    991                     id,
    992                     OUI_QCA,
    993                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE);
    994     if (gScanCommand == NULL) {
    995         ALOGE("%s: Error GScanCommand NULL", __func__);
    996         return WIFI_ERROR_UNKNOWN;
    997     }
    998 
    999     GScanCallbackHandler callbackHandler;
   1000     memset(&callbackHandler, 0, sizeof(callbackHandler));
   1001     callbackHandler.reset_significant_change = reset_significant_change_cb;
   1002 
   1003     ret = gScanCommand->setCallbackHandler(callbackHandler);
   1004     if (ret < 0)
   1005         goto cleanup;
   1006 
   1007     /* Create the NL message. */
   1008     ret = gScanCommand->create();
   1009     if (ret < 0)
   1010         goto cleanup;
   1011 
   1012     /* Set the interface Id of the message. */
   1013     ret = gScanCommand->set_iface_id(ifaceInfo->name);
   1014     if (ret < 0)
   1015         goto cleanup;
   1016 
   1017     /* Add the vendor specific attributes for the NL command. */
   1018     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
   1019     if (!nlData)
   1020         goto cleanup;
   1021 
   1022     ret = gScanCommand->put_u32(
   1023                     QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
   1024                     id);
   1025     if (ret < 0)
   1026         goto cleanup;
   1027 
   1028     gScanCommand->attr_end(nlData);
   1029 
   1030     ret = gScanCommand->allocRspParams(eGScanResetSignificantChangeRspParams);
   1031     if (ret != 0) {
   1032         ALOGE("%s: Failed to allocate memory to the response struct. "
   1033             "Error:%d", __func__, ret);
   1034         goto cleanup;
   1035     }
   1036 
   1037     gScanCommand->waitForRsp(true);
   1038     ret = gScanCommand->requestEvent();
   1039     if (ret != 0) {
   1040         ALOGE("%s: requestEvent Error:%d",__func__, ret);
   1041         goto cleanup;
   1042     }
   1043 
   1044     gScanCommand->getResetSignificantChangeRspParams((u32 *)&ret);
   1045     if (ret != 0)
   1046     {
   1047         goto cleanup;
   1048     }
   1049 
   1050     if (GScanSetSignificantChangeCmdEventHandler) {
   1051         delete GScanSetSignificantChangeCmdEventHandler;
   1052         GScanSetSignificantChangeCmdEventHandler = NULL;
   1053     }
   1054 
   1055 cleanup:
   1056     gScanCommand->freeRspParams(eGScanResetSignificantChangeRspParams);
   1057     ALOGI("%s: Delete object.", __func__);
   1058     delete gScanCommand;
   1059     return (wifi_error)ret;
   1060 }
   1061 
   1062 void get_gscan_cached_results_cb(u8 moreData, u32 numResults)
   1063 {
   1064     ALOGD("%s: More data = %d.", __func__, moreData);
   1065     ALOGD("%s: Number of cached results = %d.", __func__, numResults);
   1066 }
   1067 
   1068 /* Get the GSCAN cached scan results. */
   1069 wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface,
   1070                                                 byte flush, int max,
   1071                                                 wifi_scan_result *results,
   1072                                                 int *num)
   1073 {
   1074     int requestId, ret = 0;
   1075     wifi_scan_result *result = results;
   1076     u32 j = 0;
   1077     int i = 0;
   1078     u8 moreData = 0;
   1079     u16 waitTime = GSCAN_EVENT_WAIT_TIME_SECONDS;
   1080     GScanCommand *gScanCommand;
   1081     struct nlattr *nlData;
   1082 
   1083     interface_info *ifaceInfo = getIfaceInfo(iface);
   1084     wifi_handle wifiHandle = getWifiHandle(iface);
   1085 
   1086     if (results == NULL) {
   1087         ALOGE("%s: NULL results pointer provided. Exit.",
   1088             __func__);
   1089         return WIFI_ERROR_INVALID_ARGS;
   1090     }
   1091 
   1092     /* No request id from caller, so generate one and pass it on to the driver. */
   1093     /* Generate it randomly */
   1094     srand(time(NULL));
   1095     requestId = rand();
   1096 
   1097     ALOGE("Getting GScan Cached Results, halHandle = %p", wifiHandle);
   1098 
   1099     gScanCommand = new GScanCommand(
   1100                         wifiHandle,
   1101                         requestId,
   1102                         OUI_QCA,
   1103                         QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS);
   1104     if (gScanCommand == NULL) {
   1105         ALOGE("%s: Error GScanCommand NULL", __func__);
   1106         return WIFI_ERROR_UNKNOWN;
   1107     }
   1108 
   1109     GScanCallbackHandler callbackHandler;
   1110     memset(&callbackHandler, 0, sizeof(callbackHandler));
   1111     callbackHandler.get_cached_results = get_gscan_cached_results_cb;
   1112 
   1113     ret = gScanCommand->setCallbackHandler(callbackHandler);
   1114     if (ret < 0)
   1115         goto cleanup;
   1116 
   1117     /* Create the NL message. */
   1118     ret = gScanCommand->create();
   1119     if (ret < 0)
   1120         goto cleanup;
   1121 
   1122     /* Set the interface Id of the message. */
   1123     ret = gScanCommand->set_iface_id(ifaceInfo->name);
   1124     if (ret < 0)
   1125         goto cleanup;
   1126 
   1127     /* Add the vendor specific attributes for the NL command. */
   1128     nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
   1129     if (!nlData)
   1130         goto cleanup;
   1131 
   1132     if (ret < 0)
   1133         goto cleanup;
   1134 
   1135     if (gScanCommand->put_u32(
   1136          QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID,
   1137             requestId) ||
   1138         gScanCommand->put_u8(
   1139          QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH,
   1140             flush) ||
   1141         gScanCommand->put_u32(
   1142          QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX,
   1143             max))
   1144     {
   1145         goto cleanup;
   1146     }
   1147     gScanCommand->attr_end(nlData);
   1148     ret = gScanCommand->allocRspParams(eGScanGetCachedResultsRspParams);
   1149     if (ret != 0) {
   1150         ALOGE("%s: Failed to allocate memory fo response struct. Error:%d",
   1151             __func__, ret);
   1152         goto cleanup;
   1153     }
   1154 
   1155     gScanCommand->waitForRsp(true);
   1156     ret = gScanCommand->requestEvent();
   1157     if (ret != 0) {
   1158         ALOGE("%s: requestEvent Error:%d",__func__, ret);
   1159         goto cleanup;
   1160     }
   1161 
   1162     /* Read more data flag and number of results of retrieved cached results
   1163      * from driver/firmware.
   1164      * If more data is 0 or numResults >= max, return with results populated.
   1165      * Otherwise, loop in 4s wait for next results fragment(s).
   1166      */
   1167     ret = gScanCommand->getGetCachedResultsRspParams(max,
   1168                                                (u8 *)&moreData,
   1169                                                num,
   1170                                                results);
   1171     while (!ret && moreData && (*num < max)) {
   1172         int res = gScanCommand->timed_wait(waitTime);
   1173         if (res == ETIMEDOUT) {
   1174             ALOGE("%s: Time out happened.", __func__);
   1175             /*Proceed to cleanup & return whatever data avaiable at this time*/
   1176             goto cleanup;
   1177         }
   1178         ALOGD("%s: Command invoked return value:%d",__func__, res);
   1179         /* Read the moreData and numResults again and possibly append new
   1180          * cached results to the list.
   1181          */
   1182         ret = gScanCommand->getGetCachedResultsRspParams(max,
   1183                                                    (u8 *)&moreData,
   1184                                                    num,
   1185                                                    results);
   1186     }
   1187     if (!ret) {
   1188         for(i=0; i< *num; i++)
   1189         {
   1190             ALOGI("HAL:  Result : %d\n", i+1);
   1191             ALOGI("HAL:  ts  %lld \n", result->ts);
   1192             ALOGI("HAL:  SSID  %s \n", result->ssid);
   1193             ALOGI("HAL:  BSSID: "
   1194                "%02x:%02x:%02x:%02x:%02x:%02x \n",
   1195                result->bssid[0], result->bssid[1], result->bssid[2],
   1196                result->bssid[3], result->bssid[4], result->bssid[5]);
   1197             ALOGI("HAL:  channel %d \n", result->channel);
   1198             ALOGI("HAL:  rssi  %d \n", result->rssi);
   1199             ALOGI("HAL:  rtt  %lld \n", result->rtt);
   1200             ALOGI("HAL:  rtt_sd  %lld \n", result->rtt_sd);
   1201             ALOGI("HAL:  beacon period  %d \n",
   1202             result->beacon_period);
   1203             ALOGI("HAL:  capability  %d \n", result->capability);
   1204             ALOGI("HAL:  IE length  %d \n", result->ie_length);
   1205             ALOGI("HAL:  IE Data \n");
   1206             hexdump(result->ie_data, result->ie_length);
   1207             result = (wifi_scan_result *)
   1208                ((u8 *)&results[i] + sizeof(wifi_scan_result) +
   1209                 result->ie_length);
   1210         }
   1211     }
   1212 cleanup:
   1213     gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams);
   1214     ALOGI("%s: Delete object.", __func__);
   1215     delete gScanCommand;
   1216     return (wifi_error)ret;
   1217 }
   1218 
   1219 GScanCommand::GScanCommand(wifi_handle handle, int id, u32 vendor_id,
   1220                                   u32 subcmd)
   1221         : WifiVendorCommand(handle, id, vendor_id, subcmd)
   1222 {
   1223     ALOGD("GScanCommand %p constructed", this);
   1224     /* Initialize the member data variables here */
   1225     mStartGScanRspParams = NULL;
   1226     mStopGScanRspParams = NULL;
   1227     mSetBssidHotlistRspParams = NULL;
   1228     mResetBssidHotlistRspParams = NULL;
   1229     mSetSignificantChangeRspParams = NULL;
   1230     mResetSignificantChangeRspParams = NULL;
   1231     mGetCapabilitiesRspParams = NULL;
   1232     mGetCachedResultsRspParams = NULL;
   1233     mGetCachedResultsNumResults = 0;
   1234     mChannels = NULL;
   1235     mMaxChannels = 0;
   1236     mNumChannelsPtr = NULL;
   1237     mWaitforRsp = false;
   1238 
   1239     mRequestId = id;
   1240     memset(&mHandler, 0,sizeof(mHandler));
   1241 }
   1242 
   1243 GScanCommand::~GScanCommand()
   1244 {
   1245     ALOGD("GScanCommand %p destructor", this);
   1246     unregisterVendorHandler(mVendor_id, mSubcmd);
   1247 }
   1248 
   1249 
   1250 /* This function implements creation of Vendor command */
   1251 int GScanCommand::create() {
   1252     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
   1253     if (ret < 0) {
   1254         return ret;
   1255     }
   1256 
   1257     /* Insert the oui in the msg */
   1258     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
   1259     if (ret < 0)
   1260         goto out;
   1261     /* Insert the subcmd in the msg */
   1262     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
   1263     if (ret < 0)
   1264         goto out;
   1265 
   1266      ALOGI("%s: mVendor_id = %d, Subcmd = %d.",
   1267         __func__, mVendor_id, mSubcmd);
   1268 
   1269 out:
   1270     return ret;
   1271 }
   1272 
   1273 /* Callback handlers registered for nl message send */
   1274 static int error_handler_gscan(struct sockaddr_nl *nla, struct nlmsgerr *err,
   1275                                    void *arg)
   1276 {
   1277     struct sockaddr_nl *tmp;
   1278     int *ret = (int *)arg;
   1279     tmp = nla;
   1280     *ret = err->error;
   1281     ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret)));
   1282     return NL_STOP;
   1283 }
   1284 
   1285 /* Callback handlers registered for nl message send */
   1286 static int ack_handler_gscan(struct nl_msg *msg, void *arg)
   1287 {
   1288     int *ret = (int *)arg;
   1289     struct nl_msg * a;
   1290 
   1291     ALOGE("%s: called", __func__);
   1292     a = msg;
   1293     *ret = 0;
   1294     return NL_STOP;
   1295 }
   1296 
   1297 /* Callback handlers registered for nl message send */
   1298 static int finish_handler_gscan(struct nl_msg *msg, void *arg)
   1299 {
   1300   int *ret = (int *)arg;
   1301   struct nl_msg * a;
   1302 
   1303   ALOGE("%s: called", __func__);
   1304   a = msg;
   1305   *ret = 0;
   1306   return NL_SKIP;
   1307 }
   1308 
   1309 /*
   1310  * Override base class requestEvent and implement little differently here.
   1311  * This will send the request message.
   1312  * We don't wait for any response back in case of gscan as it is asynchronous,
   1313  * thus no wait for condition.
   1314  */
   1315 int GScanCommand::requestEvent()
   1316 {
   1317     int res = -1;
   1318     struct nl_cb *cb;
   1319 
   1320     ALOGD("%s: Entry.", __func__);
   1321 
   1322     cb = nl_cb_alloc(NL_CB_DEFAULT);
   1323     if (!cb) {
   1324         ALOGE("%s: Callback allocation failed",__func__);
   1325         res = -1;
   1326         goto out;
   1327     }
   1328 
   1329     /* Send message */
   1330     ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock);
   1331     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());
   1332     if (res < 0)
   1333         goto out;
   1334     res = 1;
   1335 
   1336     nl_cb_err(cb, NL_CB_CUSTOM, error_handler_gscan, &res);
   1337     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_gscan, &res);
   1338     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_gscan, &res);
   1339 
   1340     /* Err is populated as part of finish_handler. */
   1341     while (res > 0){
   1342          nl_recvmsgs(mInfo->cmd_sock, cb);
   1343     }
   1344 
   1345     ALOGD("%s: Msg sent, res=%d, mWaitForRsp=%d", __func__, res, mWaitforRsp);
   1346     /* Only wait for the asynchronous event if HDD returns success, res=0 */
   1347     if (!res && (mWaitforRsp == true)) {
   1348         struct timespec abstime;
   1349         abstime.tv_sec = 4;
   1350         abstime.tv_nsec = 0;
   1351         res = mCondition.wait(abstime);
   1352         if (res == ETIMEDOUT)
   1353         {
   1354             ALOGE("%s: Time out happened.", __func__);
   1355         }
   1356         ALOGD("%s: Command invoked return value:%d, mWaitForRsp=%d",
   1357             __func__, res, mWaitforRsp);
   1358     }
   1359 out:
   1360     /* Free the VendorData */
   1361     if (mVendorData) {
   1362         free(mVendorData);
   1363     }
   1364     mVendorData = NULL;
   1365     /* Cleanup the mMsg */
   1366     mMsg.destroy();
   1367     return res;
   1368 }
   1369 
   1370 int GScanCommand::requestResponse()
   1371 {
   1372     ALOGD("%s: request a response", __func__);
   1373     return WifiCommand::requestResponse(mMsg);
   1374 }
   1375 
   1376 int GScanCommand::handleResponse(WifiEvent &reply) {
   1377     ALOGI("Received a GScan response message from Driver");
   1378     u32 status;
   1379     int i = 0;
   1380     WifiVendorCommand::handleResponse(reply);
   1381 
   1382     switch(mSubcmd)
   1383     {
   1384         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS:
   1385             {
   1386                 struct nlattr *tb_vendor[
   1387                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
   1388                 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
   1389                             (struct nlattr *)mVendorData,mDataLen, NULL);
   1390 
   1391                 if (tb_vendor[
   1392                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]) {
   1393                     u32 val;
   1394                     val = nla_get_u32(
   1395                         tb_vendor[
   1396                         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]);
   1397 
   1398                     ALOGD("%s: Num channels : %d", __func__, val);
   1399                     val = val > (unsigned int)mMaxChannels ?
   1400                           (unsigned int)mMaxChannels : val;
   1401                     *mNumChannelsPtr = val;
   1402 
   1403                     /* Extract the list of channels. */
   1404                     if (*mNumChannelsPtr > 0 &&
   1405                         tb_vendor[
   1406                         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS]) {
   1407                         nla_memcpy(mChannels,
   1408                             tb_vendor[
   1409                             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS],
   1410                             sizeof(wifi_channel) * (*mNumChannelsPtr));
   1411                     }
   1412 
   1413                     ALOGD("%s: Get valid channels response received.",
   1414                         __func__);
   1415                     ALOGD("%s: Num channels : %d",
   1416                         __func__, *mNumChannelsPtr);
   1417                     ALOGD("%s: List of valid channels is: ", __func__);
   1418                     for(i = 0; i < *mNumChannelsPtr; i++)
   1419                     {
   1420                         ALOGD("%u", *(mChannels + i));
   1421                     }
   1422                 }
   1423             }
   1424             break;
   1425         default :
   1426             ALOGE("%s: Wrong GScan subcmd response received %d",
   1427                 __func__, mSubcmd);
   1428     }
   1429     return NL_SKIP;
   1430 }
   1431 
   1432 /* Called to parse and extract cached results. */
   1433 static int gscan_get_cached_results(u32 num_results,
   1434                                           wifi_scan_result *results,
   1435                                           u32 starting_index,
   1436                                           struct nlattr **tb_vendor)
   1437 {
   1438     u32 i = starting_index;
   1439     struct nlattr *scanResultsInfo;
   1440     int rem = 0;
   1441     u32 len = 0;
   1442     ALOGE("starting counter: %d", i);
   1443 
   1444     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
   1445             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
   1446             rem = nla_len(tb_vendor[
   1447             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
   1448             ]);
   1449         nla_ok(scanResultsInfo, rem);
   1450         scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
   1451     {
   1452         struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
   1453         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
   1454         (struct nlattr *) nla_data(scanResultsInfo),
   1455                 nla_len(scanResultsInfo), NULL);
   1456 
   1457         if (!
   1458             tb2[
   1459                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
   1460                 ])
   1461         {
   1462             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_TIME_STAMP"
   1463                 " not found");
   1464             return WIFI_ERROR_INVALID_ARGS;
   1465         }
   1466         results[i].ts =
   1467             nla_get_u64(
   1468             tb2[
   1469                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
   1470                 ]);
   1471         if (!
   1472             tb2[
   1473                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
   1474                 ])
   1475         {
   1476             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_SSID "
   1477                 "not found");
   1478             return WIFI_ERROR_INVALID_ARGS;
   1479         }
   1480         len = nla_len(tb2[
   1481                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
   1482         len =
   1483             sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
   1484         memcpy((void *)&results[i].ssid,
   1485             nla_data(
   1486             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
   1487         if (!
   1488             tb2[
   1489                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
   1490                 ])
   1491         {
   1492             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_BSSID "
   1493                 "not found");
   1494             return WIFI_ERROR_INVALID_ARGS;
   1495         }
   1496         len = nla_len(
   1497             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
   1498         len =
   1499             sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
   1500         memcpy(&results[i].bssid,
   1501             nla_data(
   1502             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
   1503         if (!
   1504             tb2[
   1505                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
   1506                 ])
   1507         {
   1508             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_CHANNEL "
   1509                 "not found");
   1510             return WIFI_ERROR_INVALID_ARGS;
   1511         }
   1512         results[i].channel =
   1513             nla_get_u32(
   1514             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
   1515         if (!
   1516             tb2[
   1517                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
   1518                 ])
   1519         {
   1520             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_RSSI "
   1521                 "not found");
   1522             return WIFI_ERROR_INVALID_ARGS;
   1523         }
   1524         results[i].rssi =
   1525             nla_get_u32(
   1526             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
   1527         if (!
   1528             tb2[
   1529                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
   1530                 ])
   1531         {
   1532             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_RTT "
   1533                 "not found");
   1534             return WIFI_ERROR_INVALID_ARGS;
   1535         }
   1536         results[i].rtt =
   1537             nla_get_u32(
   1538             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
   1539         if (!
   1540             tb2[
   1541                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
   1542             ])
   1543         {
   1544             ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_RTT_SD "
   1545                 "not found");
   1546             return WIFI_ERROR_INVALID_ARGS;
   1547         }
   1548         results[i].rtt_sd =
   1549             nla_get_u32(
   1550             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
   1551 
   1552         ALOGE("gscan_get_cached_results: ts  %lld ", results[i].ts);
   1553         ALOGE("gscan_get_cached_results: SSID  %s ", results[i].ssid);
   1554         ALOGE("gscan_get_cached_results: "
   1555             "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
   1556             results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
   1557             results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
   1558         ALOGE("gscan_get_cached_results: channel %d ", results[i].channel);
   1559         ALOGE("gscan_get_cached_results: rssi  %d ", results[i].rssi);
   1560         ALOGE("gscan_get_cached_results: rtt  %lld ", results[i].rtt);
   1561         ALOGE("gscan_get_cached_results: rtt_sd  %lld ", results[i].rtt_sd);
   1562         /* Increment loop index for next record */
   1563         i++;
   1564     }
   1565     ALOGE("%s: Exited the for loop", __func__);
   1566     return WIFI_SUCCESS;
   1567 }
   1568 
   1569 /* This function will be the main handler for incoming (from driver)  GSscan_SUBCMD.
   1570  *  Calls the appropriate callback handler after parsing the vendor data.
   1571  */
   1572 int GScanCommand::handleEvent(WifiEvent &event)
   1573 {
   1574     ALOGI("Got a GSCAN Event message from the Driver.");
   1575     unsigned i = 0;
   1576     u32 status;
   1577     int ret = WIFI_SUCCESS;
   1578     WifiVendorCommand::handleEvent(event);
   1579 
   1580     struct nlattr *tbVendor[
   1581         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
   1582     nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
   1583             (struct nlattr *)mVendorData,
   1584             mDataLen, NULL);
   1585 
   1586     switch(mSubcmd)
   1587     {
   1588         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
   1589         {
   1590             if (mStartGScanRspParams){
   1591                 mStartGScanRspParams->status =
   1592                     nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1593                 if (mHandler.start)
   1594                     (*mHandler.start)(mStartGScanRspParams->status);
   1595             }
   1596             waitForRsp(false);
   1597         }
   1598         break;
   1599 
   1600         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP:
   1601         {
   1602             if (mStopGScanRspParams){
   1603                 mStopGScanRspParams->status =
   1604                     nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1605                 if (mHandler.stop)
   1606                     (*mHandler.stop)(mStopGScanRspParams->status);
   1607             }
   1608             waitForRsp(false);
   1609         }
   1610         break;
   1611 
   1612         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
   1613         {
   1614             if (mSetBssidHotlistRspParams){
   1615                 mSetBssidHotlistRspParams->status =
   1616                     nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1617                 if (mHandler.set_bssid_hotlist)
   1618                     (*mHandler.set_bssid_hotlist)
   1619                             (mSetBssidHotlistRspParams->status);
   1620             }
   1621             waitForRsp(false);
   1622         }
   1623         break;
   1624 
   1625         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST:
   1626         {
   1627             if (mResetBssidHotlistRspParams){
   1628                 mResetBssidHotlistRspParams->status =
   1629                     nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1630                 if (mHandler.reset_bssid_hotlist)
   1631                     (*mHandler.reset_bssid_hotlist)
   1632                             (mResetBssidHotlistRspParams->status);
   1633             }
   1634             waitForRsp(false);
   1635         }
   1636         break;
   1637 
   1638         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
   1639         {
   1640             if (mSetSignificantChangeRspParams){
   1641                 mSetSignificantChangeRspParams->status =
   1642                     nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1643                 if (mHandler.set_significant_change)
   1644                     (*mHandler.set_significant_change)
   1645                             (mSetSignificantChangeRspParams->status);
   1646             }
   1647             waitForRsp(false);
   1648         }
   1649         break;
   1650 
   1651         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE:
   1652         {
   1653             if (mResetSignificantChangeRspParams){
   1654                 mResetSignificantChangeRspParams->status =
   1655                     nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1656                 if (mHandler.reset_significant_change)
   1657                     (*mHandler.reset_significant_change)
   1658                             (mResetSignificantChangeRspParams->status);
   1659             }
   1660             waitForRsp(false);
   1661         }
   1662         break;
   1663 
   1664         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES:
   1665         {
   1666             if (!mGetCapabilitiesRspParams){
   1667                 ALOGE("%s: mGetCapabilitiesRspParams ptr is NULL. Exit. ",
   1668                     __func__);
   1669                 break;
   1670             }
   1671 
   1672             if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]) {
   1673                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS "
   1674                     "not found", __func__);
   1675                 ret = WIFI_ERROR_INVALID_ARGS;
   1676                 break;
   1677             }
   1678             mGetCapabilitiesRspParams->status =
   1679                 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]);
   1680 
   1681             if (!tbVendor[
   1682             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
   1683                     ]) {
   1684                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
   1685                     "CAPABILITIES_MAX_SCAN_CACHE_SIZE not found", __func__);
   1686                 ret = WIFI_ERROR_INVALID_ARGS;
   1687                 break;
   1688             }
   1689             mGetCapabilitiesRspParams->capabilities.max_scan_cache_size =
   1690                 nla_get_u32(tbVendor[
   1691                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]);
   1692 
   1693             if (!tbVendor[
   1694             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
   1695                     ]) {
   1696                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
   1697                     "_SCAN_BUCKETS not found", __func__);
   1698                 ret = WIFI_ERROR_INVALID_ARGS;
   1699                 break;
   1700             }
   1701             mGetCapabilitiesRspParams->capabilities.max_scan_buckets =
   1702                 nla_get_u32(tbVendor[
   1703                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]
   1704                                 );
   1705 
   1706             if (!tbVendor[
   1707         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
   1708                     ]) {
   1709                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
   1710                     "_AP_CACHE_PER_SCAN not found", __func__);
   1711                 ret = WIFI_ERROR_INVALID_ARGS;
   1712                 break;
   1713             }
   1714             mGetCapabilitiesRspParams->capabilities.max_ap_cache_per_scan =
   1715                     nla_get_u32(tbVendor[
   1716                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]);
   1717 
   1718             if (!tbVendor[
   1719             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
   1720                     ]) {
   1721                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
   1722                     "_RSSI_SAMPLE_SIZE not found", __func__);
   1723                 ret = WIFI_ERROR_INVALID_ARGS;
   1724                 break;
   1725             }
   1726             mGetCapabilitiesRspParams->capabilities.max_rssi_sample_size =
   1727                     nla_get_u32(tbVendor[
   1728                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]);
   1729 
   1730             if (!tbVendor[
   1731             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
   1732                     ]) {
   1733                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_"
   1734                     "MAX_SCAN_REPORTING_THRESHOLD not found", __func__);
   1735                 ret = WIFI_ERROR_INVALID_ARGS;
   1736                 break;
   1737             }
   1738             mGetCapabilitiesRspParams->capabilities.max_scan_reporting_threshold =
   1739                     nla_get_u32(tbVendor[
   1740             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
   1741             ]);
   1742 
   1743             if (!tbVendor[
   1744             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS
   1745                     ]) {
   1746                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_"
   1747                     "MAX_HOTLIST_APS not found", __func__);
   1748                 ret = WIFI_ERROR_INVALID_ARGS;
   1749                 break;
   1750             }
   1751             mGetCapabilitiesRspParams->capabilities.max_hotlist_aps =
   1752                     nla_get_u32(tbVendor[
   1753                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS]);
   1754 
   1755             if (!tbVendor[
   1756             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
   1757                     ]) {
   1758                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
   1759                     "_SIGNIFICANT_WIFI_CHANGE_APS not found", __func__);
   1760                 ret = WIFI_ERROR_INVALID_ARGS;
   1761                 break;
   1762             }
   1763             mGetCapabilitiesRspParams->capabilities.max_significant_wifi_change_aps =
   1764                     nla_get_u32(tbVendor[
   1765             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]);
   1766 
   1767             if (!tbVendor[
   1768             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
   1769                     ]) {
   1770                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX"
   1771                     "_BSSID_HISTORY_ENTRIES not found", __func__);
   1772                 ret = WIFI_ERROR_INVALID_ARGS;
   1773                 break;
   1774             }
   1775             mGetCapabilitiesRspParams->capabilities.max_bssid_history_entries =
   1776                     nla_get_u32(tbVendor[
   1777             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
   1778             ]);
   1779             /* Call the call back handler func. */
   1780             if (mHandler.get_capabilities)
   1781                 (*mHandler.get_capabilities)
   1782                         (mGetCapabilitiesRspParams->status,
   1783                         mGetCapabilitiesRspParams->capabilities);
   1784             waitForRsp(false);
   1785         }
   1786         break;
   1787 
   1788         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS:
   1789         {
   1790             wifi_request_id id;
   1791             u32 resultsBufSize = 0;
   1792             u32 numResults = 0;
   1793             u32 startingIndex, sizeOfObtainedScanResults;
   1794 
   1795             if (!tbVendor[
   1796                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
   1797                 ALOGE("%s: GSCAN_RESULTS_REQUEST_ID not"
   1798                     "found", __func__);
   1799                 break;
   1800             }
   1801             id = nla_get_u32(
   1802                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
   1803                     );
   1804             ALOGE("%s: Event has Req. ID:%d, ours:%d",
   1805                 __func__, id, mRequestId);
   1806             /* If this is not for us, just ignore it. */
   1807             if (id != mRequestId) {
   1808                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
   1809                     __func__, id, mRequestId);
   1810                 break;
   1811             }
   1812             if (!tbVendor[
   1813                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
   1814                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not"
   1815                     "found", __func__);
   1816                 break;
   1817             }
   1818             numResults = nla_get_u32(tbVendor[
   1819                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
   1820             ALOGE("%s: number of results:%d", __func__,
   1821                 numResults);
   1822 
   1823             if (!mGetCachedResultsRspParams) {
   1824                 ALOGE("%s: mGetCachedResultsRspParams is NULL, exit.",
   1825                     __func__);
   1826                 break;
   1827             }
   1828 
   1829             /* Get the memory size of previous fragments, if any. */
   1830             sizeOfObtainedScanResults = mGetCachedResultsNumResults *
   1831                               sizeof(wifi_scan_result);
   1832 
   1833             mGetCachedResultsNumResults += numResults;
   1834             resultsBufSize += mGetCachedResultsNumResults *
   1835                                                 sizeof(wifi_scan_result);
   1836             /* Check if this chunck of cached scan results is a continuation of
   1837              * a previous one, i.e., a new results fragment.
   1838              */
   1839             if (mGetCachedResultsRspParams->more_data) {
   1840                 mGetCachedResultsRspParams->results = (wifi_scan_result *)
   1841                     realloc (mGetCachedResultsRspParams->results,
   1842                     resultsBufSize);
   1843             } else {
   1844                 mGetCachedResultsRspParams->results = (wifi_scan_result *)
   1845                     malloc (resultsBufSize);
   1846             }
   1847 
   1848             ALOGE("%s: Total num of cached results received: %d. \n",
   1849                 __func__, mGetCachedResultsNumResults);
   1850 
   1851             if (!mGetCachedResultsRspParams->results) {
   1852                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
   1853                     __func__);
   1854                 ret = WIFI_ERROR_OUT_OF_MEMORY;
   1855                 break;
   1856             }
   1857 
   1858             ALOGD("(u8 *)mGetCachedResultsRspParams->results : %p "
   1859                      "resultsBufSize :%d oldSizeResults : %d . \n",
   1860                      (u8 *)mGetCachedResultsRspParams->results,
   1861                      resultsBufSize, sizeOfObtainedScanResults);
   1862             /* Initialize the newly allocated memory area with 0. */
   1863             memset((u8 *)mGetCachedResultsRspParams->results +
   1864                 sizeOfObtainedScanResults,
   1865                 0,
   1866                 resultsBufSize - sizeOfObtainedScanResults);
   1867 
   1868             /* To support fragmentation from firmware, monitor the
   1869              * MORE_DTATA flag and cache results until MORE_DATA = 0.
   1870              */
   1871             if (!tbVendor[
   1872                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
   1873                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA "
   1874                     "not found", __func__);
   1875                 ret = WIFI_ERROR_INVALID_ARGS;
   1876                 break;
   1877             } else {
   1878                 mGetCachedResultsRspParams->more_data = nla_get_u8(
   1879                     tbVendor[
   1880                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
   1881                 ALOGE("%s: More data = %d. \n", __func__,
   1882                                 mGetCachedResultsRspParams->more_data);
   1883             }
   1884 
   1885             mGetCachedResultsRspParams->num_results =
   1886                                         mGetCachedResultsNumResults;
   1887             if (numResults) {
   1888                 ALOGD("%s: Extract cached results received.\n", __func__);
   1889                 startingIndex =
   1890                     mGetCachedResultsNumResults - numResults;
   1891                 ALOGD("%s: starting_index:%d",
   1892                     __func__, startingIndex);
   1893                 ret = gscan_get_cached_results(numResults,
   1894                                         mGetCachedResultsRspParams->results,
   1895                                         startingIndex,
   1896                                         tbVendor);
   1897                 /* If a parsing error occurred, exit and proceed for cleanup. */
   1898                 if (ret)
   1899                     break;
   1900             }
   1901             /* Send the results if no more result data fragments are expected. */
   1902             if (mHandler.get_cached_results) {
   1903                 (*mHandler.get_cached_results)
   1904                     (mGetCachedResultsRspParams->more_data,
   1905                     mGetCachedResultsRspParams->num_results);
   1906             }
   1907             waitForRsp(false);
   1908         }
   1909         break;
   1910 
   1911         default:
   1912             /* Error case should not happen print log */
   1913             ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd);
   1914     }
   1915 
   1916     /* A parsing error occurred, do the cleanup of gscan result lists. */
   1917     if (ret) {
   1918         switch(mSubcmd)
   1919         {
   1920             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS:
   1921             {
   1922                 freeRspParams(eGScanGetCachedResultsRspParams);
   1923             }
   1924             break;
   1925 
   1926             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES:
   1927             break;
   1928 
   1929             default:
   1930                 ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd);
   1931         }
   1932     }
   1933 
   1934     return NL_SKIP;
   1935 }
   1936 
   1937 int GScanCommand::setCallbackHandler(GScanCallbackHandler nHandler)
   1938 {
   1939     int res = 0;
   1940     mHandler = nHandler;
   1941     res = registerVendorHandler(mVendor_id, mSubcmd);
   1942     if (res != 0) {
   1943         /* Error case: should not happen, so print a log when it does. */
   1944         ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u",
   1945               __func__, mVendor_id, mSubcmd);
   1946     }
   1947     return res;
   1948 }
   1949 
   1950 /*
   1951  * Allocates memory for the subCmd response struct and initializes status = -1
   1952  */
   1953 int GScanCommand::allocRspParams(eGScanRspRarams cmd)
   1954 {
   1955     int ret = 0;
   1956     switch(cmd)
   1957     {
   1958         case eGScanStartRspParams:
   1959             mStartGScanRspParams = (GScanStartRspParams *)
   1960                 malloc(sizeof(GScanStartRspParams));
   1961             if (!mStartGScanRspParams)
   1962                 ret = -1;
   1963             else
   1964                 mStartGScanRspParams->status = -1;
   1965         break;
   1966         case eGScanStopRspParams:
   1967             mStopGScanRspParams = (GScanStopRspParams *)
   1968                 malloc(sizeof(GScanStopRspParams));
   1969             if (!mStopGScanRspParams)
   1970                 ret = -1;
   1971             else
   1972                 mStopGScanRspParams->status = -1;
   1973         break;
   1974         case eGScanSetBssidHotlistRspParams:
   1975             mSetBssidHotlistRspParams = (GScanSetBssidHotlistRspParams *)
   1976                 malloc(sizeof(GScanSetBssidHotlistRspParams));
   1977             if (!mSetBssidHotlistRspParams)
   1978                 ret = -1;
   1979             else
   1980                 mSetBssidHotlistRspParams->status = -1;
   1981         break;
   1982         case eGScanResetBssidHotlistRspParams:
   1983             mResetBssidHotlistRspParams = (GScanResetBssidHotlistRspParams *)
   1984                 malloc(sizeof(GScanResetBssidHotlistRspParams));
   1985             if (!mResetBssidHotlistRspParams)
   1986                 ret = -1;
   1987             else
   1988                 mResetBssidHotlistRspParams->status = -1;
   1989         break;
   1990         case eGScanSetSignificantChangeRspParams:
   1991             mSetSignificantChangeRspParams =
   1992                 (GScanSetSignificantChangeRspParams *)
   1993                 malloc(sizeof(GScanSetSignificantChangeRspParams));
   1994             if (!mSetSignificantChangeRspParams)
   1995                 ret = -1;
   1996             else
   1997                 mSetSignificantChangeRspParams->status = -1;
   1998         break;
   1999         case eGScanResetSignificantChangeRspParams:
   2000             mResetSignificantChangeRspParams =
   2001                 (GScanResetSignificantChangeRspParams *)
   2002                 malloc(sizeof(GScanResetSignificantChangeRspParams));
   2003             if (!mResetSignificantChangeRspParams)
   2004                 ret = -1;
   2005             else
   2006                 mResetSignificantChangeRspParams->status = -1;
   2007         break;
   2008         case eGScanGetCapabilitiesRspParams:
   2009             mGetCapabilitiesRspParams = (GScanGetCapabilitiesRspParams *)
   2010                 malloc(sizeof(GScanGetCapabilitiesRspParams));
   2011             if (!mGetCapabilitiesRspParams)
   2012                 ret = -1;
   2013             else  {
   2014                 memset(&mGetCapabilitiesRspParams->capabilities, 0,
   2015                     sizeof(wifi_gscan_capabilities));
   2016                 mGetCapabilitiesRspParams->status = -1;
   2017             }
   2018         break;
   2019         case eGScanGetCachedResultsRspParams:
   2020             mGetCachedResultsRspParams = (GScanGetCachedResultsRspParams *)
   2021                 malloc(sizeof(GScanGetCachedResultsRspParams));
   2022             if (!mGetCachedResultsRspParams)
   2023                 ret = -1;
   2024             else {
   2025                 mGetCachedResultsRspParams->num_results = 0;
   2026                 mGetCachedResultsRspParams->more_data = false;
   2027                 mGetCachedResultsRspParams->results = NULL;
   2028             }
   2029         break;
   2030         default:
   2031             ALOGD("%s: Wrong request for alloc.", __func__);
   2032             ret = -1;
   2033     }
   2034     return ret;
   2035 }
   2036 
   2037 void GScanCommand::freeRspParams(eGScanRspRarams cmd)
   2038 {
   2039     switch(cmd)
   2040     {
   2041         case eGScanStartRspParams:
   2042             if (mStartGScanRspParams) {
   2043                 free(mStartGScanRspParams);
   2044                 mStartGScanRspParams = NULL;
   2045             }
   2046         break;
   2047         case eGScanStopRspParams:
   2048             if (mStopGScanRspParams) {
   2049                 free(mStopGScanRspParams);
   2050                 mStopGScanRspParams = NULL;
   2051             }
   2052         break;
   2053         case eGScanSetBssidHotlistRspParams:
   2054             if (mSetBssidHotlistRspParams) {
   2055                 free(mSetBssidHotlistRspParams);
   2056                 mSetBssidHotlistRspParams = NULL;
   2057             }
   2058         break;
   2059         case eGScanResetBssidHotlistRspParams:
   2060             if (mResetBssidHotlistRspParams) {
   2061                 free(mResetBssidHotlistRspParams);
   2062                 mResetBssidHotlistRspParams = NULL;
   2063             }
   2064         break;
   2065         case eGScanSetSignificantChangeRspParams:
   2066             if (mSetSignificantChangeRspParams) {
   2067                 free(mSetSignificantChangeRspParams);
   2068                 mSetSignificantChangeRspParams = NULL;
   2069             }
   2070         break;
   2071         case eGScanResetSignificantChangeRspParams:
   2072             if (mResetSignificantChangeRspParams) {
   2073                 free(mResetSignificantChangeRspParams);
   2074                 mResetSignificantChangeRspParams = NULL;
   2075             }
   2076         break;
   2077         case eGScanGetCapabilitiesRspParams:
   2078             if (mGetCapabilitiesRspParams) {
   2079                 free(mGetCapabilitiesRspParams);
   2080                 mGetCapabilitiesRspParams = NULL;
   2081             }
   2082         break;
   2083         case eGScanGetCachedResultsRspParams:
   2084             if (mGetCachedResultsRspParams) {
   2085                 if (mGetCachedResultsRspParams->results) {
   2086                     free(mGetCachedResultsRspParams->results);
   2087                     mGetCachedResultsRspParams->results = NULL;
   2088                 }
   2089                 free(mGetCachedResultsRspParams);
   2090                 mGetCachedResultsRspParams = NULL;
   2091             }
   2092         break;
   2093 
   2094         default:
   2095             ALOGD("%s: Wrong request for free.", __func__);
   2096     }
   2097 }
   2098 
   2099 wifi_error GScanCommand::getGetCachedResultsRspParams(
   2100                                                     int max,
   2101                                                     u8 *moreData,
   2102                                                     int *numResults,
   2103                                                     wifi_scan_result *results)
   2104 {
   2105     wifi_error ret = WIFI_SUCCESS;
   2106 
   2107     if (mGetCachedResultsRspParams && results)
   2108     {
   2109         *moreData = mGetCachedResultsRspParams->more_data;
   2110         *numResults = mGetCachedResultsRspParams->num_results > (unsigned int)max ?
   2111                         max : mGetCachedResultsRspParams->num_results;
   2112         memcpy(results,
   2113             mGetCachedResultsRspParams->results,
   2114             *numResults * sizeof(wifi_scan_result));
   2115     } else {
   2116         ALOGD("%s: mGetCachedResultsRspParams is NULL", __func__);
   2117         ret = WIFI_ERROR_INVALID_ARGS;
   2118     }
   2119     return ret;
   2120 }
   2121 
   2122 void GScanCommand::getGetCapabilitiesRspParams(
   2123                                         wifi_gscan_capabilities *capabilities,
   2124                                         u32 *status)
   2125 {
   2126     if (mGetCapabilitiesRspParams && capabilities)
   2127     {
   2128         *status = mGetCapabilitiesRspParams->status;
   2129         memcpy(capabilities,
   2130             &mGetCapabilitiesRspParams->capabilities,
   2131             sizeof(wifi_gscan_capabilities));
   2132     } else {
   2133         ALOGD("%s: mGetCapabilitiesRspParams is NULL", __func__);
   2134     }
   2135 }
   2136 
   2137 void GScanCommand::getStartGScanRspParams(u32 *status)
   2138 {
   2139     if (mStartGScanRspParams)
   2140     {
   2141         *status = mStartGScanRspParams->status;
   2142     } else {
   2143         ALOGD("%s: mStartGScanRspParams is NULL", __func__);
   2144     }
   2145 }
   2146 
   2147 void GScanCommand::getStopGScanRspParams(u32 *status)
   2148 {
   2149     if (mStopGScanRspParams)
   2150     {
   2151         *status = mStopGScanRspParams->status;
   2152     } else {
   2153         ALOGD("%s: mStopGScanRspParams is NULL", __func__);
   2154     }
   2155 }
   2156 
   2157 void GScanCommand::getSetBssidHotlistRspParams(u32 *status)
   2158 {
   2159     if (mSetBssidHotlistRspParams)
   2160     {
   2161         *status = mSetBssidHotlistRspParams->status;
   2162     } else {
   2163         ALOGD("%s: mSetBssidHotlistRspParams is NULL", __func__);
   2164     }
   2165 }
   2166 
   2167 void GScanCommand::getResetBssidHotlistRspParams(u32 *status)
   2168 {
   2169     if (mResetBssidHotlistRspParams)
   2170     {
   2171         *status = mResetBssidHotlistRspParams->status;
   2172     } else {
   2173         ALOGD("%s: mResetBssidHotlistRspParams is NULL", __func__);
   2174     }
   2175 }
   2176 
   2177 void GScanCommand::getSetSignificantChangeRspParams(u32 *status)
   2178 {
   2179     if (mSetSignificantChangeRspParams)
   2180     {
   2181         *status = mSetSignificantChangeRspParams->status;
   2182     } else {
   2183         ALOGD("%s: mSetSignificantChangeRspParams is NULL", __func__);
   2184     }
   2185 }
   2186 
   2187 void GScanCommand::getResetSignificantChangeRspParams(u32 *status)
   2188 {
   2189     if (mResetSignificantChangeRspParams)
   2190     {
   2191         *status = mResetSignificantChangeRspParams->status;
   2192     } else {
   2193         ALOGD("%s: mResetSignificantChangeRspParams is NULL", __func__);
   2194     }
   2195 }
   2196 
   2197 int GScanCommand::timed_wait(u16 wait_time)
   2198 {
   2199     struct timespec absTime;
   2200     int res;
   2201     absTime.tv_sec = wait_time;
   2202     absTime.tv_nsec = 0;
   2203     return mCondition.wait(absTime);
   2204 }
   2205 
   2206 void GScanCommand::waitForRsp(bool wait)
   2207 {
   2208     mWaitforRsp = wait;
   2209 }
   2210 
   2211 void GScanCommand::setMaxChannels(int max_channels) {
   2212     mMaxChannels = max_channels;
   2213 }
   2214 
   2215 void GScanCommand::setChannels(int *channels) {
   2216     mChannels = channels;
   2217 }
   2218 
   2219 void GScanCommand::setNumChannelsPtr(int *num_channels) {
   2220     mNumChannelsPtr = num_channels;
   2221 }
   2222 
   2223