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 "gscan_event_handler.h"
     18 #include "vendor_definitions.h"
     19 
     20 /* This function implements creation of Vendor command event handler. */
     21 int GScanCommandEventHandler::create() {
     22     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
     23     if (ret < 0) {
     24         return ret;
     25     }
     26 
     27     /* Insert the oui in the msg */
     28     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
     29     if (ret < 0)
     30         goto out;
     31 
     32     /* Insert the subcmd in the msg */
     33     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
     34     if (ret < 0)
     35         goto out;
     36 out:
     37     return ret;
     38 }
     39 
     40 int GScanCommandEventHandler::get_request_id()
     41 {
     42     return mRequestId;
     43 }
     44 
     45 GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id,
     46                                                 u32 vendor_id,
     47                                                 u32 subcmd,
     48                                                 GScanCallbackHandler handler)
     49         : WifiVendorCommand(handle, id, vendor_id, subcmd)
     50 {
     51     int ret = 0;
     52     ALOGD("GScanCommandEventHandler %p constructed", this);
     53     mRequestId = id;
     54     mHandler = handler;
     55     mSubCommandId = subcmd;
     56     mHotlistApFoundResults = NULL;
     57     mHotlistApFoundNumResults = 0;
     58     mHotlistApFoundMoreData = false;
     59     mSignificantChangeResults = NULL;
     60     mSignificantChangeNumResults = 0;
     61     mSignificantChangeMoreData = false;
     62 
     63     switch(mSubCommandId)
     64     {
     65         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
     66         {
     67             /* Register handlers for northbound asychronous scan events. */
     68             ALOGD("%s: wait for GSCAN_RESULTS_AVAILABLE, "
     69                 "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __func__);
     70             ret = registerVendorHandler(mVendor_id,
     71                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE) ||
     72                   registerVendorHandler(mVendor_id,
     73                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) ||
     74                   registerVendorHandler(mVendor_id,
     75                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT);
     76             if (ret < 0)
     77                 ALOGD("%s: Error in registering handler for "
     78                     "GSCAN_START. \n", __func__);
     79         }
     80         break;
     81 
     82         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
     83         {
     84             ret = registerVendorHandler(mVendor_id,
     85                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE);
     86             if (ret < 0)
     87                 ALOGD("%s: Error in registering handler for "
     88                     "GSCAN_SIGNIFICANT_CHANGE. \n", __func__);
     89         }
     90         break;
     91 
     92         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
     93         {
     94             ret = registerVendorHandler(mVendor_id,
     95                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND);
     96             if (ret < 0)
     97                 ALOGD("%s: Error in registering handler for"
     98                     " GSCAN_HOTLIST_AP_FOUND. \n", __func__);
     99         }
    100         break;
    101     }
    102 }
    103 
    104 GScanCommandEventHandler::~GScanCommandEventHandler()
    105 {
    106     ALOGD("GScanCommandEventHandler %p destructor", this);
    107     switch(mSubCommandId)
    108     {
    109         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
    110         {
    111             /* Unregister event handlers. */
    112             ALOGD("%s: Unregister handlers for GSCAN_RESULTS_AVAILABLE, "
    113             "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __func__);
    114             unregisterVendorHandler(mVendor_id,
    115                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE);
    116             unregisterVendorHandler(mVendor_id,
    117                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT);
    118             unregisterVendorHandler(mVendor_id,
    119                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT);
    120         }
    121         break;
    122 
    123         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
    124         {
    125             unregisterVendorHandler(mVendor_id,
    126                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE);
    127         }
    128         break;
    129 
    130         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
    131         {
    132             unregisterVendorHandler(mVendor_id,
    133                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND);
    134         }
    135         break;
    136     }
    137 }
    138 
    139 static wifi_error gscan_get_hotlist_ap_found_results(u32 num_results,
    140                                             wifi_scan_result *results,
    141                                             u32 starting_index,
    142                                             struct nlattr **tb_vendor)
    143 {
    144     u32 i = starting_index;
    145     struct nlattr *scanResultsInfo;
    146     int rem = 0;
    147     u32 len = 0;
    148     ALOGE("gscan_get_hotlist_ap_found_results: starting counter: %d", i);
    149 
    150     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
    151             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
    152             rem = nla_len(tb_vendor[
    153             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
    154             ]);
    155                 nla_ok(scanResultsInfo, rem);
    156                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
    157     {
    158         struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
    159         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
    160         (struct nlattr *) nla_data(scanResultsInfo),
    161                 nla_len(scanResultsInfo), NULL);
    162 
    163         if (!
    164             tb2[
    165                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
    166                 ])
    167         {
    168             ALOGE("gscan_get_hotlist_ap_found_results: "
    169                 "RESULTS_SCAN_RESULT_TIME_STAMP not found");
    170             return WIFI_ERROR_INVALID_ARGS;
    171         }
    172         results[i].ts =
    173             nla_get_u64(
    174             tb2[
    175                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
    176                 ]);
    177         if (!
    178             tb2[
    179                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
    180                 ])
    181         {
    182             ALOGE("gscan_get_hotlist_ap_found_results: "
    183                 "RESULTS_SCAN_RESULT_SSID not found");
    184             return WIFI_ERROR_INVALID_ARGS;
    185         }
    186         len = nla_len(tb2[
    187                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
    188         len =
    189             sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
    190         memcpy((void *)&results[i].ssid,
    191             nla_data(
    192             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
    193         if (!
    194             tb2[
    195                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
    196                 ])
    197         {
    198             ALOGE("gscan_get_hotlist_ap_found_results: "
    199                 "RESULTS_SCAN_RESULT_BSSID not found");
    200             return WIFI_ERROR_INVALID_ARGS;
    201         }
    202         len = nla_len(
    203             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
    204         len =
    205             sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
    206         memcpy(&results[i].bssid,
    207             nla_data(
    208             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
    209         if (!
    210             tb2[
    211                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
    212                 ])
    213         {
    214             ALOGE("gscan_get_hotlist_ap_found_results: "
    215                 "RESULTS_SCAN_RESULT_CHANNEL not found");
    216             return WIFI_ERROR_INVALID_ARGS;
    217         }
    218         results[i].channel =
    219             nla_get_u32(
    220             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
    221         if (!
    222             tb2[
    223                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
    224                 ])
    225         {
    226             ALOGE("gscan_get_hotlist_ap_found_results: "
    227                 "RESULTS_SCAN_RESULT_RSSI not found");
    228             return WIFI_ERROR_INVALID_ARGS;
    229         }
    230         results[i].rssi =
    231             nla_get_u32(
    232             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
    233         if (!
    234             tb2[
    235                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
    236                 ])
    237         {
    238             ALOGE("gscan_get_hotlist_ap_found_results: "
    239                 "RESULTS_SCAN_RESULT_RTT not found");
    240             return WIFI_ERROR_INVALID_ARGS;
    241         }
    242         results[i].rtt =
    243             nla_get_u32(
    244             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
    245         if (!
    246             tb2[
    247                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
    248             ])
    249         {
    250             ALOGE("gscan_get_hotlist_ap_found_results: "
    251                 "RESULTS_SCAN_RESULT_RTT_SD not found");
    252             return WIFI_ERROR_INVALID_ARGS;
    253         }
    254         results[i].rtt_sd =
    255             nla_get_u32(
    256             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
    257 
    258         ALOGE("gscan_get_hotlist_ap_found_results: ts  %lld ", results[i].ts);
    259         ALOGE("gscan_get_hotlist_ap_found_results: SSID  %s ",
    260             results[i].ssid) ;
    261         ALOGE("gscan_get_hotlist_ap_found_results: "
    262             "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
    263             results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
    264             results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
    265         ALOGE("gscan_get_hotlist_ap_found_results: channel %d ",
    266             results[i].channel);
    267         ALOGE("gscan_get_hotlist_ap_found_results: rssi %d ", results[i].rssi);
    268         ALOGE("gscan_get_hotlist_ap_found_results: rtt %lld ", results[i].rtt);
    269         ALOGE("gscan_get_hotlist_ap_found_results: rtt_sd %lld ",
    270             results[i].rtt_sd);
    271         /* Increment loop index for next record */
    272         i++;
    273     }
    274     return WIFI_SUCCESS;
    275 }
    276 
    277 static wifi_error gscan_get_significant_change_results(u32 num_results,
    278                                     wifi_significant_change_result **results,
    279                                     u32 starting_index,
    280                                     struct nlattr **tb_vendor)
    281 {
    282     u32 i = starting_index;
    283     int j;
    284     int rem = 0;
    285     u32 len = 0;
    286     struct nlattr *scanResultsInfo;
    287 
    288     ALOGE("gscan_get_significant_change_results: starting counter: %d", i);
    289 
    290     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
    291             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
    292             rem = nla_len(tb_vendor[
    293             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
    294         nla_ok(scanResultsInfo, rem);
    295         scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
    296     {
    297         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
    298         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
    299             (struct nlattr *) nla_data(scanResultsInfo),
    300                 nla_len(scanResultsInfo), NULL);
    301         if (!
    302             tb2[
    303             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID
    304             ])
    305         {
    306             ALOGE("gscan_get_significant_change_results: "
    307                 "SIGNIFICANT_CHANGE_RESULT_BSSID not found");
    308             return WIFI_ERROR_INVALID_ARGS;
    309         }
    310         len = nla_len(
    311             tb2[
    312             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]
    313             );
    314         len =
    315             sizeof(results[i]->bssid) <= len ? sizeof(results[i]->bssid) : len;
    316         memcpy(&results[i]->bssid[0],
    317             nla_data(
    318             tb2[
    319         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]),
    320             len);
    321         ALOGI("\nsignificant_change_result:%d, BSSID:"
    322             "%02x:%02x:%02x:%02x:%02x:%02x \n", i, results[i]->bssid[0],
    323             results[i]->bssid[1], results[i]->bssid[2], results[i]->bssid[3],
    324             results[i]->bssid[4], results[i]->bssid[5]);
    325 
    326         if (!
    327             tb2[
    328         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL
    329                 ])
    330         {
    331             ALOGE("gscan_get_significant_change_results: "
    332                 "SIGNIFICANT_CHANGE_RESULT_CHANNEL not found");
    333             return WIFI_ERROR_INVALID_ARGS;
    334         }
    335         results[i]->channel =
    336             nla_get_u32(
    337             tb2[
    338         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL]);
    339         ALOGI("significant_change_result:%d, channel:%d.\n",
    340             i, results[i]->channel);
    341 
    342         if (!
    343             tb2[
    344         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
    345             ])
    346         {
    347             ALOGE("gscan_get_significant_change_results: "
    348                 "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found");
    349             return WIFI_ERROR_INVALID_ARGS;
    350         }
    351         results[i]->num_rssi =
    352             nla_get_u32(
    353             tb2[
    354         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI]);
    355         ALOGI("gscan_get_significant_change_results: "
    356             "significant_change_result:%d, num_rssi:%d.\n",
    357             i, results[i]->num_rssi);
    358 
    359         if (!
    360             tb2[
    361         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST
    362             ])
    363         {
    364             ALOGE("gscan_get_significant_change_results: "
    365                 "SIGNIFICANT_CHANGE_RESULT_RSSI_LIST not found");
    366             return WIFI_ERROR_INVALID_ARGS;
    367         }
    368         ALOGI("gscan_get_significant_change_results: before reading the RSSI "
    369             "list: num_rssi:%d, size_of_rssi:%d, total size:%d, ",
    370             results[i]->num_rssi,
    371             sizeof(wifi_rssi), results[i]->num_rssi * sizeof(wifi_rssi));
    372 
    373         memcpy(&(results[i]->rssi[0]),
    374             nla_data(
    375             tb2[
    376         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST]
    377             ), results[i]->num_rssi * sizeof(wifi_rssi));
    378 
    379         for (j = 0; j < results[i]->num_rssi; j++)
    380             ALOGI("     significant_change_result: %d, rssi[%d]:%d, ",
    381             i, j, results[i]->rssi[j]);
    382 
    383         /* Increment loop index to prase next record. */
    384         i++;
    385     }
    386     return WIFI_SUCCESS;
    387 }
    388 
    389 /* This function will be the main handler for incoming (from driver)  GSscan_SUBCMD.
    390  *  Calls the appropriate callback handler after parsing the vendor data.
    391  */
    392 int GScanCommandEventHandler::handleEvent(WifiEvent &event)
    393 {
    394     ALOGI("GScanCommandEventHandler::handleEvent: Got a GSCAN Event"
    395         " message from the Driver.");
    396     unsigned i=0;
    397     int ret = WIFI_SUCCESS;
    398     u32 status;
    399     wifi_scan_result *result;
    400     struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
    401 
    402     WifiVendorCommand::handleEvent(event);
    403 
    404     nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
    405                         (struct nlattr *)mVendorData,
    406                         mDataLen, NULL);
    407 
    408     switch(mSubcmd)
    409     {
    410         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
    411         {
    412             wifi_request_id reqId;
    413             u32 len = 0;
    414             u32 resultsBufSize = 0;
    415             u32 lengthOfInfoElements = 0;
    416 
    417             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT "
    418                 "received.");
    419 
    420             if (!tbVendor[
    421                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
    422             {
    423                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
    424                     __func__);
    425                 ret = WIFI_ERROR_INVALID_ARGS;
    426                 break;
    427             }
    428             reqId = nla_get_u32(
    429                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
    430                     );
    431             /* If this is not for us, just ignore it. */
    432             if (reqId != mRequestId) {
    433                 ALOGE("%s: Event has Req. ID:%d <> Ours:%d, ignore it.",
    434                     __func__, reqId, mRequestId);
    435                 break;
    436             }
    437 
    438             /* Parse and extract the results. */
    439             if (!
    440                 tbVendor[
    441                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
    442                 ])
    443             {
    444                 ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __func__);
    445                 ret = WIFI_ERROR_INVALID_ARGS;
    446                 break;
    447             }
    448             lengthOfInfoElements =
    449                 nla_get_u32(
    450                 tbVendor[
    451                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
    452             ALOGI("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d",
    453                 __func__, lengthOfInfoElements);
    454             resultsBufSize =
    455                 lengthOfInfoElements + sizeof(wifi_scan_result);
    456             result = (wifi_scan_result *) malloc (resultsBufSize);
    457             if (!result) {
    458                 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
    459                     __func__);
    460                 ret = WIFI_ERROR_OUT_OF_MEMORY;
    461                 break;
    462             }
    463             memset(result, 0, resultsBufSize);
    464 
    465             result->ie_length = lengthOfInfoElements;
    466 
    467             /* Extract and fill out the wifi_scan_result struct. */
    468             if (!
    469             tbVendor[
    470                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
    471                 ])
    472             {
    473                 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
    474                     __func__);
    475                 ret = WIFI_ERROR_INVALID_ARGS;
    476                 break;
    477             }
    478             result->ts =
    479                 nla_get_u64(
    480                 tbVendor[
    481                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
    482                     ]);
    483 
    484             if (!
    485                 tbVendor[
    486                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
    487                     ])
    488             {
    489                 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __func__);
    490                 ret = WIFI_ERROR_INVALID_ARGS;
    491                 break;
    492             }
    493             len = nla_len(tbVendor[
    494                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
    495             len =
    496                 sizeof(result->ssid) <= len ? sizeof(result->ssid) : len;
    497             memcpy((void *)&result->ssid,
    498                 nla_data(
    499                 tbVendor[
    500                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
    501 
    502             if (!
    503                 tbVendor[
    504                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
    505                     ])
    506             {
    507                 ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __func__);
    508                 ret = WIFI_ERROR_INVALID_ARGS;
    509                 break;
    510             }
    511             len = nla_len(
    512                 tbVendor[
    513                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
    514             len =
    515                 sizeof(result->bssid) <= len ? sizeof(result->bssid) : len;
    516             memcpy(&result->bssid,
    517                 nla_data(
    518                 tbVendor[
    519                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
    520 
    521             if (!
    522                 tbVendor[
    523                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
    524                     ])
    525             {
    526                 ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __func__);
    527                 ret = WIFI_ERROR_INVALID_ARGS;
    528                 break;
    529             }
    530             result->channel =
    531                 nla_get_u32(
    532                 tbVendor[
    533                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
    534 
    535             if (!
    536                 tbVendor[
    537                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
    538                     ])
    539             {
    540                 ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __func__);
    541                 ret = WIFI_ERROR_INVALID_ARGS;
    542                 break;
    543             }
    544             result->rssi =
    545                 nla_get_u32(
    546                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]
    547                 );
    548 
    549             if (!
    550                 tbVendor[
    551                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
    552                     ])
    553             {
    554                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __func__);
    555                 ret = WIFI_ERROR_INVALID_ARGS;
    556                 break;
    557             }
    558             result->rtt =
    559                 nla_get_u32(
    560                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
    561 
    562             if (!
    563                 tbVendor[
    564                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
    565                 ])
    566             {
    567                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __func__);
    568                 ret = WIFI_ERROR_INVALID_ARGS;
    569                 break;
    570             }
    571             result->rtt_sd =
    572                 nla_get_u32(
    573                 tbVendor[
    574                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
    575 
    576             if (!
    577                 tbVendor[
    578                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
    579             {
    580                 ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
    581                     __func__);
    582                 ret = WIFI_ERROR_INVALID_ARGS;
    583                 break;
    584             }
    585             result->beacon_period =
    586                 nla_get_u16(
    587                 tbVendor[
    588                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
    589 
    590             if (!
    591                 tbVendor[
    592                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
    593                     ])
    594             {
    595                 ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __func__);
    596                 ret = WIFI_ERROR_INVALID_ARGS;
    597                 break;
    598             }
    599             result->capability =
    600                 nla_get_u16(
    601                 tbVendor[
    602                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
    603 
    604             if (!
    605                 tbVendor[
    606                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
    607                 ])
    608             {
    609                 ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __func__);
    610                 ret = WIFI_ERROR_INVALID_ARGS;
    611                 break;
    612             }
    613             memcpy(&(result->ie_data[0]),
    614                 nla_data(tbVendor[
    615                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
    616                 lengthOfInfoElements);
    617 
    618             ALOGE("handleEvent:FULL_SCAN_RESULTS: ts  %lld ", result->ts);
    619             ALOGE("handleEvent:FULL_SCAN_RESULTS: SSID  %s ", result->ssid) ;
    620             ALOGE("handleEvent:FULL_SCAN_RESULTS: "
    621                 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
    622                 result->bssid[0], result->bssid[1], result->bssid[2],
    623                 result->bssid[3], result->bssid[4], result->bssid[5]);
    624             ALOGE("handleEvent:FULL_SCAN_RESULTS: channel %d ",
    625                 result->channel);
    626             ALOGE("handleEvent:FULL_SCAN_RESULTS: rssi  %d ", result->rssi);
    627             ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt  %lld ", result->rtt);
    628             ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt_sd  %lld ",
    629                 result->rtt_sd);
    630             ALOGE("handleEvent:FULL_SCAN_RESULTS: beacon period  %d ",
    631                 result->beacon_period);
    632             ALOGE("handleEvent:FULL_SCAN_RESULTS: capability  %d ",
    633                 result->capability);
    634             ALOGE("handleEvent:FULL_SCAN_RESULTS: IE length  %d ",
    635                 result->ie_length);
    636 
    637             ALOGE("%s: Invoking the callback. \n", __func__);
    638             if (mHandler.on_full_scan_result) {
    639                 (*mHandler.on_full_scan_result)(reqId, result);
    640                 /* Reset flag and num counter. */
    641                 free(result);
    642                 result = NULL;
    643             }
    644         }
    645         break;
    646 
    647         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
    648         {
    649             wifi_request_id id;
    650             u32 numResults = 0;
    651 
    652             ALOGD("Event "
    653                 "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE "
    654                 "received.");
    655 
    656             if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
    657                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID"
    658                     "not found. Exit", __func__);
    659                 ret = WIFI_ERROR_INVALID_ARGS;
    660                 break;
    661             }
    662             id = nla_get_u32(
    663                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
    664                     );
    665             /* If this is not for us, then ignore it. */
    666             if (id != mRequestId) {
    667                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
    668                     __func__, id, mRequestId);
    669                 break;
    670             }
    671             if (!tbVendor[
    672                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
    673                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
    674                     __func__);
    675                 ret = WIFI_ERROR_INVALID_ARGS;
    676                 break;
    677             }
    678             numResults = nla_get_u32(tbVendor[
    679                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
    680             ALOGE("%s: number of results:%d", __func__, numResults);
    681 
    682             /* Invoke the callback func to report the number of results. */
    683             ALOGE("%s: Calling on_scan_results_available handler",
    684                 __func__);
    685             if (!mHandler.on_scan_results_available) {
    686                 break;
    687             }
    688             (*mHandler.on_scan_results_available)(id, numResults);
    689         }
    690         break;
    691 
    692         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
    693         {
    694             wifi_request_id id;
    695             u32 resultsBufSize = 0;
    696             u32 numResults = 0;
    697             u32 startingIndex, sizeOfObtainedResults;
    698 
    699             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND "
    700                 "received.");
    701 
    702             id = nla_get_u32(
    703                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
    704                     );
    705             /* If this is not for us, just ignore it. */
    706             if (id != mRequestId) {
    707                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
    708                     __func__, id, mRequestId);
    709                 break;
    710             }
    711             if (!tbVendor[
    712                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
    713                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
    714                     __func__);
    715                 ret = WIFI_ERROR_INVALID_ARGS;
    716                 break;
    717             }
    718             numResults = nla_get_u32(tbVendor[
    719                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
    720             ALOGE("%s: number of results:%d", __func__, numResults);
    721 
    722             /* Get the memory size of previous fragments, if any. */
    723             sizeOfObtainedResults = mHotlistApFoundNumResults *
    724                           sizeof(wifi_scan_result);
    725 
    726             mHotlistApFoundNumResults += numResults;
    727             resultsBufSize += mHotlistApFoundNumResults *
    728                                             sizeof(wifi_scan_result);
    729 
    730             /* Check if this chunck of scan results is a continuation of
    731              * a previous one.
    732              */
    733             if (mHotlistApFoundMoreData) {
    734                 mHotlistApFoundResults = (wifi_scan_result *)
    735                             realloc (mHotlistApFoundResults, resultsBufSize);
    736             } else {
    737                 mHotlistApFoundResults = (wifi_scan_result *)
    738                             malloc (resultsBufSize);
    739             }
    740 
    741             if (!mHotlistApFoundResults) {
    742                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
    743                     __func__);
    744                 ret = WIFI_ERROR_OUT_OF_MEMORY;
    745                 break;
    746             }
    747             /* Initialize the newly allocated memory area with 0. */
    748             memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0,
    749                     resultsBufSize - sizeOfObtainedResults);
    750 
    751             ALOGE("%s: Num of AP FOUND results = %d. \n", __func__,
    752                                             mHotlistApFoundNumResults);
    753 
    754             /* To support fragmentation from firmware, monitor the
    755              * MORE_DTATA flag and cache results until MORE_DATA = 0.
    756              * Only then we can pass on the results to framework through
    757              * the callback function.
    758              */
    759             if (!tbVendor[
    760                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
    761                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
    762                     " found", __func__);
    763                 ret = WIFI_ERROR_INVALID_ARGS;
    764                 break;
    765             } else {
    766                 mHotlistApFoundMoreData = nla_get_u8(
    767                     tbVendor[
    768                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
    769                 ALOGE("%s: More data = %d. \n",
    770                     __func__, mHotlistApFoundMoreData);
    771             }
    772 
    773             ALOGE("%s: Extract hotlist_ap_found results.\n", __func__);
    774             startingIndex = mHotlistApFoundNumResults - numResults;
    775             ALOGE("%s: starting_index:%d",
    776                 __func__, startingIndex);
    777             ret = gscan_get_hotlist_ap_found_results(numResults,
    778                                                 mHotlistApFoundResults,
    779                                                 startingIndex,
    780                                                 tbVendor);
    781             /* If a parsing error occurred, exit and proceed for cleanup. */
    782             if (ret)
    783                 break;
    784             /* Send the results if no more result data fragments are expected. */
    785             if (!mHotlistApFoundMoreData) {
    786                 (*mHandler.on_hotlist_ap_found)(id,
    787                                                 mHotlistApFoundNumResults,
    788                                                 mHotlistApFoundResults);
    789                 /* Reset flag and num counter. */
    790                 free(mHotlistApFoundResults);
    791                 mHotlistApFoundResults = NULL;
    792                 mHotlistApFoundMoreData = false;
    793                 mHotlistApFoundNumResults = 0;
    794             }
    795         }
    796         break;
    797 
    798         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
    799         {
    800             wifi_request_id reqId;
    801             u32 numResults = 0, sizeOfObtainedResults;
    802             u32 startingIndex, index = 0;
    803             struct nlattr *scanResultsInfo;
    804             int rem = 0;
    805 
    806             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE "
    807                 "received.");
    808 
    809             if (!tbVendor[
    810                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
    811             {
    812                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
    813                     __func__);
    814                 ret = WIFI_ERROR_INVALID_ARGS;
    815                 break;
    816             }
    817             reqId = nla_get_u32(
    818                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
    819                     );
    820             /* If this is not for us, just ignore it. */
    821             if (reqId != mRequestId) {
    822                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
    823                     __func__, reqId, mRequestId);
    824                 break;
    825             }
    826             if (!tbVendor[
    827                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE])
    828             {
    829                 ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found."
    830                     "Exit.", __func__);
    831                 ret = WIFI_ERROR_INVALID_ARGS;
    832                 break;
    833             }
    834             numResults = nla_get_u32(tbVendor[
    835                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
    836             /* Get the memory size of previous fragments, if any. */
    837             sizeOfObtainedResults = sizeof(wifi_significant_change_result *) *
    838                                 mSignificantChangeNumResults;
    839 
    840             index = mSignificantChangeNumResults;
    841             mSignificantChangeNumResults += numResults;
    842             /*
    843              * Check if this chunck of wifi_significant_change results is a
    844              * continuation of a previous one.
    845              */
    846             if (mSignificantChangeMoreData) {
    847                 mSignificantChangeResults =
    848                     (wifi_significant_change_result **)
    849                         realloc (mSignificantChangeResults,
    850                         sizeof(wifi_significant_change_result *) *
    851                                 mSignificantChangeNumResults);
    852             } else {
    853                 mSignificantChangeResults =
    854                     (wifi_significant_change_result **)
    855                         malloc (sizeof(wifi_significant_change_result *) *
    856                                 mSignificantChangeNumResults);
    857             }
    858 
    859             if (!mSignificantChangeResults) {
    860                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
    861                     __func__);
    862                 ret = WIFI_ERROR_OUT_OF_MEMORY;
    863                 break;
    864             }
    865             /* Initialize the newly allocated memory area with 0. */
    866             memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0,
    867                     sizeof(wifi_significant_change_result *) *
    868                                 numResults);
    869             ALOGD("%s: mSignificantChangeMoreData = %d",
    870                     __func__, mSignificantChangeMoreData);
    871 
    872             for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[
    873                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
    874                 rem = nla_len(tbVendor[
    875                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
    876                 nla_ok(scanResultsInfo, rem);
    877                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
    878             {
    879                 u32 num_rssi = 0;
    880                 u32 resultsBufSize = 0;
    881                 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
    882                 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
    883                     (struct nlattr *) nla_data(scanResultsInfo),
    884                     nla_len(scanResultsInfo), NULL);
    885                 if (!tb2[
    886                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
    887                     ])
    888                 {
    889                     ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
    890                         "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. "
    891                         "Exit.", __func__);
    892                     ret = WIFI_ERROR_INVALID_ARGS;
    893                     break;
    894                 }
    895                 num_rssi = nla_get_u32(tb2[
    896                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
    897                         ]);
    898                 resultsBufSize = sizeof(wifi_significant_change_result) +
    899                             num_rssi * sizeof(wifi_rssi);
    900                 mSignificantChangeResults[index] =
    901                     (wifi_significant_change_result *) malloc (resultsBufSize);
    902 
    903                 if (!mSignificantChangeResults[index]) {
    904                     ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
    905                         __func__);
    906                     ret = WIFI_ERROR_OUT_OF_MEMORY;
    907                     break;
    908                 }
    909                 /* Initialize the newly allocated memory area with 0. */
    910                 memset((u8 *)mSignificantChangeResults[index],
    911                         0, resultsBufSize);
    912 
    913                 ALOGE("%s: For Significant Change results[%d], num_rssi:%d\n",
    914                     __func__, index, num_rssi);
    915                 index++;
    916             }
    917 
    918             ALOGE("%s: Extract significant change results.\n", __func__);
    919             startingIndex =
    920                 mSignificantChangeNumResults - numResults;
    921             ret = gscan_get_significant_change_results(numResults,
    922                                                 mSignificantChangeResults,
    923                                                 startingIndex,
    924                                                 tbVendor);
    925             /* If a parsing error occurred, exit and proceed for cleanup. */
    926             if (ret)
    927                 break;
    928             /* To support fragmentation from firmware, monitor the
    929              * MORE_DTATA flag and cache results until MORE_DATA = 0.
    930              * Only then we can pass on the results to framework through
    931              * the callback function.
    932              */
    933             if (!tbVendor[
    934                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
    935                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
    936                     " found. Stop parsing and exit.", __func__);
    937                 break;
    938             }
    939             mSignificantChangeMoreData = nla_get_u8(
    940                 tbVendor[
    941                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
    942             ALOGE("%s: More data = %d. \n",
    943                 __func__, mSignificantChangeMoreData);
    944 
    945             /* Send the results if no more result fragments are expected */
    946             if (!mSignificantChangeMoreData) {
    947                 ALOGE("%s: Invoking the callback. \n", __func__);
    948                 (*mHandler.on_significant_change)(reqId,
    949                                               mSignificantChangeNumResults,
    950                                               mSignificantChangeResults);
    951                 /* Reset flag and num counter. */
    952                 for (index = 0; index  < mSignificantChangeNumResults; index++)
    953                 {
    954                     free(mSignificantChangeResults[index]);
    955                     mSignificantChangeResults[index] = NULL;
    956                 }
    957                 free(mSignificantChangeResults);
    958                 mSignificantChangeResults = NULL;
    959                 mSignificantChangeNumResults = 0;
    960                 mSignificantChangeMoreData = false;
    961             }
    962         }
    963         break;
    964 
    965         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
    966         {
    967             wifi_scan_event scanEvent;
    968             u32 scanEventStatus = 0;
    969             wifi_request_id reqId;
    970 
    971             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT "
    972                 "received.");
    973 
    974             if (!tbVendor[
    975                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
    976             {
    977                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
    978                     __func__);
    979                 ret = WIFI_ERROR_INVALID_ARGS;
    980                 break;
    981             }
    982             reqId = nla_get_u32(
    983                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
    984                     );
    985             /* If this is not for us, just ignore it. */
    986             if (reqId != mRequestId) {
    987                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
    988                     __func__, reqId, mRequestId);
    989                 break;
    990             }
    991 
    992             if (!tbVendor[
    993                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) {
    994                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not"
    995                     " found. Stop parsing and exit.", __func__);
    996                 break;
    997             }
    998             scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[
    999                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]);
   1000 
   1001             if (!tbVendor[
   1002                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]) {
   1003                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_STATUS not"
   1004                     " found. Stop parsing and exit.", __func__);
   1005                 break;
   1006             }
   1007             scanEventStatus = nla_get_u32(tbVendor[
   1008                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]);
   1009 
   1010             ALOGE("%s: Scan event type: %d, status = %d. \n", __func__,
   1011                                     scanEvent, scanEventStatus);
   1012             /* Send the results if no more result fragments are expected. */
   1013             (*mHandler.on_scan_event)(scanEvent, scanEventStatus);
   1014         }
   1015         break;
   1016 
   1017         default:
   1018             /* Error case should not happen print log */
   1019             ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd);
   1020     }
   1021 
   1022     /* A parsing error occurred, do the cleanup of gscan result lists. */
   1023     if (ret) {
   1024         switch(mSubcmd)
   1025         {
   1026             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
   1027             {
   1028                 free(result);
   1029                 result = NULL;
   1030             }
   1031             break;
   1032 
   1033             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
   1034             {
   1035                 /* Reset flag and num counter. */
   1036                 free(mHotlistApFoundResults);
   1037                 mHotlistApFoundResults = NULL;
   1038                 mHotlistApFoundMoreData = false;
   1039                 mHotlistApFoundNumResults = 0;
   1040             }
   1041             break;
   1042 
   1043             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
   1044             {
   1045                 for (i = 0; i < mSignificantChangeNumResults; i++)
   1046                 {
   1047                     if (mSignificantChangeResults[i]) {
   1048                         free(mSignificantChangeResults[i]);
   1049                         mSignificantChangeResults[i] = NULL;
   1050                     }
   1051                 }
   1052                 free(mSignificantChangeResults);
   1053                 mSignificantChangeResults = NULL;
   1054                 mSignificantChangeNumResults = 0;
   1055                 mSignificantChangeMoreData = false;
   1056             }
   1057             break;
   1058 
   1059             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
   1060             break;
   1061 
   1062             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
   1063             break;
   1064 
   1065             default:
   1066                 ALOGE("%s: Parsing err handler: wrong GScan subcmd "
   1067                     "received %d", __func__, mSubcmd);
   1068         }
   1069     }
   1070     return NL_SKIP;
   1071 }
   1072