• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG  "WifiHAL"
18 
19 #include <utils/Log.h>
20 #include "gscan_event_handler.h"
21 #include "vendor_definitions.h"
22 
23 /* This function implements creation of Vendor command event handler. */
create()24 int GScanCommandEventHandler::create() {
25     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
26     if (ret < 0) {
27         return ret;
28     }
29 
30     /* Insert the oui in the msg */
31     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
32     if (ret < 0)
33         goto out;
34 
35     /* Insert the subcmd in the msg */
36     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
37     if (ret < 0)
38         goto out;
39 out:
40     return ret;
41 }
42 
get_request_id()43 int GScanCommandEventHandler::get_request_id()
44 {
45     return mRequestId;
46 }
47 
set_request_id(int request_id)48 void GScanCommandEventHandler::set_request_id(int request_id)
49 {
50     mRequestId = request_id;
51 }
52 
enableEventHandling()53 void GScanCommandEventHandler::enableEventHandling()
54 {
55     mEventHandlingEnabled = true;
56 }
57 
disableEventHandling()58 void GScanCommandEventHandler::disableEventHandling()
59 {
60     mEventHandlingEnabled = false;
61 }
62 
isEventHandlingEnabled()63 bool GScanCommandEventHandler::isEventHandlingEnabled()
64 {
65     return mEventHandlingEnabled;
66 }
67 
setCallbackHandler(GScanCallbackHandler handler)68 void GScanCommandEventHandler::setCallbackHandler(GScanCallbackHandler handler)
69 {
70     mHandler = handler;
71 }
72 
GScanCommandEventHandler(wifi_handle handle,int id,u32 vendor_id,u32 subcmd,GScanCallbackHandler handler)73 GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id,
74                                                 u32 vendor_id,
75                                                 u32 subcmd,
76                                                 GScanCallbackHandler handler)
77         : WifiVendorCommand(handle, id, vendor_id, subcmd)
78 {
79     int ret = 0;
80     ALOGD("GScanCommandEventHandler %p constructed", this);
81     mRequestId = id;
82     mHandler = handler;
83     mSubCommandId = subcmd;
84     mHotlistApFoundResults = NULL;
85     mHotlistApFoundNumResults = 0;
86     mHotlistApFoundMoreData = false;
87     mHotlistApLostResults = NULL;
88     mHotlistApLostNumResults = 0;
89     mHotlistApLostMoreData = false;
90     mSignificantChangeResults = NULL;
91     mSignificantChangeNumResults = 0;
92     mSignificantChangeMoreData = false;
93     mHotlistSsidFoundNumResults = 0;
94     mHotlistSsidFoundMoreData = false;
95     mHotlistSsidLostNumResults = 0;
96     mHotlistSsidLostMoreData = false;
97     mHotlistSsidFoundResults = NULL;
98     mHotlistSsidLostResults = NULL;
99     mPnoNetworkFoundResults = NULL;
100     mPnoNetworkFoundNumResults = 0;
101     mPnoNetworkFoundMoreData = false;
102     mPasspointNetworkFoundResult = NULL;
103     mPasspointAnqp = NULL;
104     mPasspointAnqpLen = 0;
105     mPasspointNetId = -1;
106     mEventHandlingEnabled = false;
107 
108     switch(mSubCommandId)
109     {
110         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
111         {
112             /* Register handlers for northbound asychronous scan events. */
113             ALOGD("%s: wait for GSCAN_RESULTS_AVAILABLE, "
114                 "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __FUNCTION__);
115             ret = registerVendorHandler(mVendor_id,
116                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE) ||
117                   registerVendorHandler(mVendor_id,
118                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) ||
119                   registerVendorHandler(mVendor_id,
120                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT);
121             if (ret)
122                 ALOGD("%s: Error in registering handler for "
123                     "GSCAN_START. \n", __FUNCTION__);
124         }
125         break;
126 
127         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
128         {
129             ret = registerVendorHandler(mVendor_id,
130                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE);
131             if (ret)
132                 ALOGD("%s: Error in registering handler for "
133                     "GSCAN_SIGNIFICANT_CHANGE. \n", __FUNCTION__);
134         }
135         break;
136 
137         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
138         {
139             ret = registerVendorHandler(mVendor_id,
140                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND);
141             if (ret)
142                 ALOGD("%s: Error in registering handler for"
143                     " GSCAN_HOTLIST_AP_FOUND. \n", __FUNCTION__);
144 
145             ret = registerVendorHandler(mVendor_id,
146                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST);
147             if (ret)
148                 ALOGD("%s: Error in registering handler for"
149                     " GSCAN_HOTLIST_AP_LOST. \n", __FUNCTION__);
150         }
151         break;
152 
153         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST:
154         {
155             ret = registerVendorHandler(mVendor_id,
156                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND);
157             if (ret)
158                 ALOGD("%s: Error in registering handler for"
159                     " GSCAN_HOTLIST_SSID_FOUND. \n", __FUNCTION__);
160 
161             ret = registerVendorHandler(mVendor_id,
162                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST);
163             if (ret)
164                 ALOGD("%s: Error in registering handler for"
165                     " GSCAN_HOTLIST_SSID_LOST. \n", __FUNCTION__);
166         }
167         break;
168 
169         case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST:
170         {
171             ret = registerVendorHandler(mVendor_id,
172                     QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND);
173             if (ret)
174                 ALOGD("%s: Error in registering handler for"
175                     " PNO_NETWORK_FOUND. \n", __FUNCTION__);
176         }
177         break;
178 
179         case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST:
180         {
181             ret = registerVendorHandler(mVendor_id,
182                 QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND);
183             if (ret)
184                 ALOGD("%s: Error in registering handler for"
185                     " PNO_PASSPOINT_NETWORK_FOUND. \n", __FUNCTION__);
186         }
187         break;
188     }
189 }
190 
~GScanCommandEventHandler()191 GScanCommandEventHandler::~GScanCommandEventHandler()
192 {
193     ALOGD("GScanCommandEventHandler %p destructor", this);
194     switch(mSubCommandId)
195     {
196         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
197         {
198             /* Unregister event handlers. */
199             ALOGD("%s: Unregister handlers for GSCAN_RESULTS_AVAILABLE, "
200             "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __FUNCTION__);
201             unregisterVendorHandler(mVendor_id,
202                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE);
203             unregisterVendorHandler(mVendor_id,
204                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT);
205             unregisterVendorHandler(mVendor_id,
206                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT);
207         }
208         break;
209 
210         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
211         {
212             unregisterVendorHandler(mVendor_id,
213                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE);
214         }
215         break;
216 
217         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
218         {
219             unregisterVendorHandler(mVendor_id,
220                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND);
221             unregisterVendorHandler(mVendor_id,
222                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST);
223         }
224         break;
225 
226         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST:
227         {
228             unregisterVendorHandler(mVendor_id,
229                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND);
230             unregisterVendorHandler(mVendor_id,
231                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST);
232         }
233         break;
234 
235         case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST:
236         {
237             unregisterVendorHandler(mVendor_id,
238                 QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND);
239         }
240         break;
241 
242         case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST:
243         {
244             unregisterVendorHandler(mVendor_id,
245                 QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND);
246         }
247         break;
248     }
249 }
250 
gscan_parse_hotlist_ap_results(u32 num_results,wifi_scan_result * results,u32 starting_index,struct nlattr ** tb_vendor)251 wifi_error GScanCommandEventHandler::gscan_parse_hotlist_ap_results(
252                                             u32 num_results,
253                                             wifi_scan_result *results,
254                                             u32 starting_index,
255                                             struct nlattr **tb_vendor)
256 {
257     u32 i = starting_index;
258     struct nlattr *scanResultsInfo;
259     int rem = 0;
260     u32 len = 0;
261     ALOGE("gscan_parse_hotlist_ap_results: starting counter: %d", i);
262 
263     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
264             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
265             rem = nla_len(tb_vendor[
266             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
267             ]);
268                 nla_ok(scanResultsInfo, rem);
269                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
270     {
271         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
272         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
273         (struct nlattr *) nla_data(scanResultsInfo),
274                 nla_len(scanResultsInfo), NULL);
275 
276         if (!
277             tb2[
278                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
279                 ])
280         {
281             ALOGE("gscan_parse_hotlist_ap_results: "
282                 "RESULTS_SCAN_RESULT_TIME_STAMP not found");
283             return WIFI_ERROR_INVALID_ARGS;
284         }
285         results[i].ts =
286             nla_get_u64(
287             tb2[
288                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
289                 ]);
290         if (!
291             tb2[
292                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
293                 ])
294         {
295             ALOGE("gscan_parse_hotlist_ap_results: "
296                 "RESULTS_SCAN_RESULT_SSID not found");
297             return WIFI_ERROR_INVALID_ARGS;
298         }
299         len = nla_len(tb2[
300                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
301         len =
302             sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
303         memcpy((void *)&results[i].ssid,
304             nla_data(
305             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
306         if (!
307             tb2[
308                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
309                 ])
310         {
311             ALOGE("gscan_parse_hotlist_ap_results: "
312                 "RESULTS_SCAN_RESULT_BSSID not found");
313             return WIFI_ERROR_INVALID_ARGS;
314         }
315         len = nla_len(
316             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
317         len =
318             sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
319         memcpy(&results[i].bssid,
320             nla_data(
321             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
322         if (!
323             tb2[
324                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
325                 ])
326         {
327             ALOGE("gscan_parse_hotlist_ap_results: "
328                 "RESULTS_SCAN_RESULT_CHANNEL not found");
329             return WIFI_ERROR_INVALID_ARGS;
330         }
331         results[i].channel =
332             nla_get_u32(
333             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
334         if (!
335             tb2[
336                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
337                 ])
338         {
339             ALOGE("gscan_parse_hotlist_ap_results: "
340                 "RESULTS_SCAN_RESULT_RSSI not found");
341             return WIFI_ERROR_INVALID_ARGS;
342         }
343         results[i].rssi =
344             get_s32(
345             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
346         if (!
347             tb2[
348                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
349                 ])
350         {
351             ALOGE("gscan_parse_hotlist_ap_results: "
352                 "RESULTS_SCAN_RESULT_RTT not found");
353             return WIFI_ERROR_INVALID_ARGS;
354         }
355         results[i].rtt =
356             nla_get_u32(
357             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
358         if (!
359             tb2[
360                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
361             ])
362         {
363             ALOGE("gscan_parse_hotlist_ap_results: "
364                 "RESULTS_SCAN_RESULT_RTT_SD not found");
365             return WIFI_ERROR_INVALID_ARGS;
366         }
367         results[i].rtt_sd =
368             nla_get_u32(
369             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
370 
371         ALOGE("gscan_parse_hotlist_ap_results: ts  %lld ", results[i].ts);
372         ALOGE("gscan_parse_hotlist_ap_results: SSID  %s ",
373             results[i].ssid) ;
374         ALOGE("gscan_parse_hotlist_ap_results: "
375             "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
376             results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
377             results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
378         ALOGE("gscan_parse_hotlist_ap_results: channel %d ",
379             results[i].channel);
380         ALOGE("gscan_parse_hotlist_ap_results: rssi %d ", results[i].rssi);
381         ALOGE("gscan_parse_hotlist_ap_results: rtt %lld ", results[i].rtt);
382         ALOGE("gscan_parse_hotlist_ap_results: rtt_sd %lld ",
383             results[i].rtt_sd);
384         /* Increment loop index for next record */
385         i++;
386     }
387     return WIFI_SUCCESS;
388 }
389 
gscan_get_significant_change_results(u32 num_results,wifi_significant_change_result ** results,u32 starting_index,struct nlattr ** tb_vendor)390 static wifi_error gscan_get_significant_change_results(u32 num_results,
391                                     wifi_significant_change_result **results,
392                                     u32 starting_index,
393                                     struct nlattr **tb_vendor)
394 {
395     u32 i = starting_index;
396     int j;
397     int rem = 0;
398     u32 len = 0;
399     struct nlattr *scanResultsInfo;
400 
401     ALOGI("gscan_get_significant_change_results: starting counter: %d", i);
402 
403     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
404             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
405             rem = nla_len(tb_vendor[
406             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
407         nla_ok(scanResultsInfo, rem);
408         scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
409     {
410         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
411         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
412             (struct nlattr *) nla_data(scanResultsInfo),
413                 nla_len(scanResultsInfo), NULL);
414         if (!
415             tb2[
416             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID
417             ])
418         {
419             ALOGE("gscan_get_significant_change_results: "
420                 "SIGNIFICANT_CHANGE_RESULT_BSSID not found");
421             return WIFI_ERROR_INVALID_ARGS;
422         }
423         len = nla_len(
424             tb2[
425             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]
426             );
427         len =
428             sizeof(results[i]->bssid) <= len ? sizeof(results[i]->bssid) : len;
429         memcpy(&results[i]->bssid[0],
430             nla_data(
431             tb2[
432         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]),
433             len);
434         ALOGI("\nsignificant_change_result:%d, BSSID:"
435             "%02x:%02x:%02x:%02x:%02x:%02x \n", i, results[i]->bssid[0],
436             results[i]->bssid[1], results[i]->bssid[2], results[i]->bssid[3],
437             results[i]->bssid[4], results[i]->bssid[5]);
438 
439         if (!
440             tb2[
441         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL
442                 ])
443         {
444             ALOGE("gscan_get_significant_change_results: "
445                 "SIGNIFICANT_CHANGE_RESULT_CHANNEL not found");
446             return WIFI_ERROR_INVALID_ARGS;
447         }
448         results[i]->channel =
449             nla_get_u32(
450             tb2[
451         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL]);
452         ALOGI("significant_change_result:%d, channel:%d.\n",
453             i, results[i]->channel);
454 
455         if (!
456             tb2[
457         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
458             ])
459         {
460             ALOGE("gscan_get_significant_change_results: "
461                 "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found");
462             return WIFI_ERROR_INVALID_ARGS;
463         }
464         results[i]->num_rssi =
465             nla_get_u32(
466             tb2[
467         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI]);
468         ALOGI("gscan_get_significant_change_results: "
469             "significant_change_result:%d, num_rssi:%d.\n",
470             i, results[i]->num_rssi);
471 
472         if (!
473             tb2[
474         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST
475             ])
476         {
477             ALOGE("gscan_get_significant_change_results: "
478                 "SIGNIFICANT_CHANGE_RESULT_RSSI_LIST not found");
479             return WIFI_ERROR_INVALID_ARGS;
480         }
481         ALOGI("gscan_get_significant_change_results: before reading the RSSI "
482             "list: num_rssi:%d, size_of_rssi:%d, total size:%d, ",
483             results[i]->num_rssi,
484             sizeof(wifi_rssi), results[i]->num_rssi * sizeof(wifi_rssi));
485 
486         memcpy(&(results[i]->rssi[0]),
487             nla_data(
488             tb2[
489         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST]
490             ), results[i]->num_rssi * sizeof(wifi_rssi));
491 
492         for (j = 0; j < results[i]->num_rssi; j++)
493             ALOGI("     significant_change_result: %d, rssi[%d]:%d, ",
494             i, j, results[i]->rssi[j]);
495 
496         /* Increment loop index to prase next record. */
497         i++;
498     }
499     return WIFI_SUCCESS;
500 }
501 
gscan_parse_hotlist_ssid_results(u32 num_results,wifi_scan_result * results,u32 starting_index,struct nlattr ** tb_vendor)502 wifi_error GScanCommandEventHandler::gscan_parse_hotlist_ssid_results(
503                                             u32 num_results,
504                                             wifi_scan_result *results,
505                                             u32 starting_index,
506                                             struct nlattr **tb_vendor)
507 {
508     u32 i = starting_index;
509     struct nlattr *scanResultsInfo;
510     int rem = 0;
511     u32 len = 0;
512     ALOGI("gscan_parse_hotlist_ssid_results: starting counter: %d", i);
513 
514     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
515             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
516             rem = nla_len(tb_vendor[
517             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
518             ]);
519                 nla_ok(scanResultsInfo, rem);
520                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
521     {
522         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
523         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
524         (struct nlattr *) nla_data(scanResultsInfo),
525                 nla_len(scanResultsInfo), NULL);
526 
527         if (!
528             tb2[
529                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
530                 ])
531         {
532             ALOGE("gscan_parse_hotlist_ssid_results: "
533                 "RESULTS_SCAN_RESULT_TIME_STAMP not found");
534             return WIFI_ERROR_INVALID_ARGS;
535         }
536         results[i].ts =
537             nla_get_u64(
538             tb2[
539                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
540                 ]);
541         if (!
542             tb2[
543                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
544                 ])
545         {
546             ALOGE("gscan_parse_hotlist_ssid_results: "
547                 "RESULTS_SCAN_RESULT_SSID not found");
548             return WIFI_ERROR_INVALID_ARGS;
549         }
550         len = nla_len(tb2[
551                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
552         len =
553             sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
554         memcpy((void *)&results[i].ssid,
555             nla_data(
556             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
557         if (!
558             tb2[
559                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
560                 ])
561         {
562             ALOGE("gscan_parse_hotlist_ssid_results: "
563                 "RESULTS_SCAN_RESULT_BSSID not found");
564             return WIFI_ERROR_INVALID_ARGS;
565         }
566         len = nla_len(
567             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
568         len =
569             sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
570         memcpy(&results[i].bssid,
571             nla_data(
572             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
573         if (!
574             tb2[
575                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
576                 ])
577         {
578             ALOGE("gscan_parse_hotlist_ssid_results: "
579                 "RESULTS_SCAN_RESULT_CHANNEL not found");
580             return WIFI_ERROR_INVALID_ARGS;
581         }
582         results[i].channel =
583             nla_get_u32(
584             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
585         if (!
586             tb2[
587                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
588                 ])
589         {
590             ALOGE("gscan_parse_hotlist_ssid_results: "
591                 "RESULTS_SCAN_RESULT_RSSI not found");
592             return WIFI_ERROR_INVALID_ARGS;
593         }
594         results[i].rssi =
595             get_s32(
596             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
597         if (!
598             tb2[
599                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
600                 ])
601         {
602             ALOGE("gscan_parse_hotlist_ssid_results: "
603                 "RESULTS_SCAN_RESULT_RTT not found");
604             return WIFI_ERROR_INVALID_ARGS;
605         }
606         results[i].rtt =
607             nla_get_u32(
608             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
609         if (!
610             tb2[
611                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
612             ])
613         {
614             ALOGE("gscan_parse_hotlist_ssid_results: "
615                 "RESULTS_SCAN_RESULT_RTT_SD not found");
616             return WIFI_ERROR_INVALID_ARGS;
617         }
618         results[i].rtt_sd =
619             nla_get_u32(
620             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
621 
622         ALOGD("gscan_parse_hotlist_ssid_results: ts  %lld ", results[i].ts);
623         ALOGD("gscan_parse_hotlist_ssid_results: SSID  %s ",
624             results[i].ssid) ;
625         ALOGD("gscan_parse_hotlist_ssid_results: "
626             "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
627             results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
628             results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
629         ALOGD("gscan_parse_hotlist_ssid_results: channel %d ",
630             results[i].channel);
631         ALOGD("gscan_parse_hotlist_ssid_results: rssi %d ", results[i].rssi);
632         ALOGD("gscan_parse_hotlist_ssid_results: rtt %lld ", results[i].rtt);
633         ALOGD("gscan_parse_hotlist_ssid_results: rtt_sd %lld ",
634             results[i].rtt_sd);
635         /* Increment loop index for next record */
636         i++;
637     }
638     return WIFI_SUCCESS;
639 }
640 
gscan_parse_passpoint_network_result(struct nlattr ** tb_vendor)641 wifi_error GScanCommandEventHandler::gscan_parse_passpoint_network_result(
642             struct nlattr **tb_vendor)
643 {
644     struct nlattr *scanResultsInfo, *wifiScanResultsInfo;
645     u32 resultsBufSize = 0;
646     u32 len = 0;
647     int rem = 0;
648     ALOGI("%s: Entering", __FUNCTION__);
649 
650     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
651             QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST]),
652             rem = nla_len(tb_vendor[
653             QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST
654             ]);
655                 nla_ok(scanResultsInfo, rem);
656                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
657     {
658         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
659         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
660         (struct nlattr *) nla_data(scanResultsInfo),
661                 nla_len(scanResultsInfo), NULL);
662 
663         if (!
664             tb2[
665                 QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID
666                 ])
667         {
668             ALOGE("%s: GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID not found",
669                   __FUNCTION__);
670             return WIFI_ERROR_INVALID_ARGS;
671         }
672         mPasspointNetId =
673             nla_get_u32(
674             tb2[
675                 QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID
676                 ]);
677 
678         for (wifiScanResultsInfo = (struct nlattr *) nla_data(tb2[
679              QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
680              rem = nla_len(tb2[
681              QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
682              ]);
683              nla_ok(wifiScanResultsInfo, rem);
684              wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(rem)))
685         {
686             struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
687             nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
688             (struct nlattr *) nla_data(wifiScanResultsInfo),
689                      nla_len(wifiScanResultsInfo), NULL);
690 
691             resultsBufSize = sizeof(wifi_scan_result);
692             if (!
693                 tb3[
694                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
695                 ])
696             {
697                 ALOGE("%s: RESULTS_SCAN_RESULT_IE_LENGTH not found", __FUNCTION__);
698                 return WIFI_ERROR_INVALID_ARGS;
699             }
700             resultsBufSize +=
701                 nla_get_u32(
702                 tb3[
703                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
704 
705             /* Allocate the appropriate memory for mPasspointNetworkFoundResult */
706             mPasspointNetworkFoundResult = (wifi_scan_result *)
707                                 malloc (resultsBufSize);
708 
709             if (!mPasspointNetworkFoundResult) {
710                 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
711                     __FUNCTION__);
712                 return WIFI_ERROR_OUT_OF_MEMORY;
713             }
714             memset(mPasspointNetworkFoundResult, 0, resultsBufSize);
715 
716             mPasspointNetworkFoundResult->ie_length =
717                 nla_get_u32(
718                 tb3[
719                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
720 
721             if (!
722                 tb3[
723                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
724                     ])
725             {
726                 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
727                       __FUNCTION__);
728                 return WIFI_ERROR_INVALID_ARGS;
729             }
730             mPasspointNetworkFoundResult->ts =
731                 nla_get_u64(
732                 tb3[
733                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
734                     ]);
735             if (!
736                 tb3[
737                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
738                     ])
739             {
740                 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __FUNCTION__);
741                 return WIFI_ERROR_INVALID_ARGS;
742             }
743              len = nla_len(tb3[
744                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
745              len =
746                  sizeof(mPasspointNetworkFoundResult->ssid) <= len ?
747                  sizeof(mPasspointNetworkFoundResult->ssid) : len;
748              memcpy((void *)&(mPasspointNetworkFoundResult->ssid[0]),
749                  nla_data(
750                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
751              if (!
752                  tb3[
753                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
754                      ])
755              {
756                  ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __FUNCTION__);
757                  return WIFI_ERROR_INVALID_ARGS;
758              }
759              len = nla_len(
760                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
761              len =
762                  sizeof(mPasspointNetworkFoundResult->bssid) <= len ?
763                  sizeof(mPasspointNetworkFoundResult->bssid) : len;
764              memcpy(&(mPasspointNetworkFoundResult->bssid[0]),
765                  nla_data(
766                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]),
767                  len);
768              if (!
769                  tb3[
770                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
771                      ])
772              {
773                  ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __FUNCTION__);
774                  return WIFI_ERROR_INVALID_ARGS;
775              }
776              mPasspointNetworkFoundResult->channel =
777                  nla_get_u32(
778                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
779              if (!
780                  tb3[
781                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
782                      ])
783              {
784                  ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __FUNCTION__);
785                  return WIFI_ERROR_INVALID_ARGS;
786              }
787              mPasspointNetworkFoundResult->rssi =
788                  get_s32(
789                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
790              if (!
791                  tb3[
792                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
793                      ])
794              {
795                  ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __FUNCTION__);
796                  return WIFI_ERROR_INVALID_ARGS;
797              }
798              mPasspointNetworkFoundResult->rtt =
799                  nla_get_u32(
800                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
801              if (!
802                  tb3[
803                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
804                  ])
805              {
806                  ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __FUNCTION__);
807                  return WIFI_ERROR_INVALID_ARGS;
808              }
809              mPasspointNetworkFoundResult->rtt_sd =
810                  nla_get_u32(
811                  tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
812 
813              if (!
814                  tb3[
815                  QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
816              {
817                  ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
818                      __FUNCTION__);
819                  return WIFI_ERROR_INVALID_ARGS;
820              }
821              mPasspointNetworkFoundResult->beacon_period =
822                  nla_get_u16(
823                  tb3[
824                  QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
825 
826              if (!
827                  tb3[
828                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
829                      ])
830              {
831                  ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__);
832                  return WIFI_ERROR_INVALID_ARGS;
833              }
834              mPasspointNetworkFoundResult->capability =
835                  nla_get_u16(
836                  tb3[
837                  QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
838 
839              if (!
840                  tb3[
841                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
842                  ])
843              {
844                  ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __FUNCTION__);
845                  return WIFI_ERROR_INVALID_ARGS;
846              }
847              memcpy(&(mPasspointNetworkFoundResult->ie_data[0]),
848                  nla_data(tb3[
849                      QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
850                  mPasspointNetworkFoundResult->ie_length);
851 
852              ALOGD("%s: ts  %lld ", __FUNCTION__,
853                  mPasspointNetworkFoundResult->ts);
854              ALOGD("%s: SSID  %s ", __FUNCTION__,
855                  mPasspointNetworkFoundResult->ssid);
856              ALOGD("%s: BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
857                  __FUNCTION__,
858                  mPasspointNetworkFoundResult->bssid[0],
859                  mPasspointNetworkFoundResult->bssid[1],
860                  mPasspointNetworkFoundResult->bssid[2],
861                  mPasspointNetworkFoundResult->bssid[3],
862                  mPasspointNetworkFoundResult->bssid[4],
863                  mPasspointNetworkFoundResult->bssid[5]);
864              ALOGD("%s: channel %d ", __FUNCTION__,
865                  mPasspointNetworkFoundResult->channel);
866              ALOGD("%s: rssi  %d ", __FUNCTION__,
867                  mPasspointNetworkFoundResult->rssi);
868              ALOGD("%s: rtt  %lld ", __FUNCTION__,
869                  mPasspointNetworkFoundResult->rtt);
870              ALOGD("%s: rtt_sd  %lld ", __FUNCTION__,
871                  mPasspointNetworkFoundResult->rtt_sd);
872              ALOGD("%s: ie_length  %lld ", __FUNCTION__,
873                  mPasspointNetworkFoundResult->ie_length);
874              ALOGD("%s: ie_data", __FUNCTION__);
875              hexdump(mPasspointNetworkFoundResult->ie_data,
876                      mPasspointNetworkFoundResult->ie_length);
877         }
878 
879         if (!
880            tb2[
881                QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN
882            ])
883         {
884             ALOGE("%s:PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN not found",
885                   __FUNCTION__);
886             return WIFI_ERROR_INVALID_ARGS;
887         }
888         mPasspointAnqpLen =
889             nla_get_u32(
890                 tb2[
891                 QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN]);
892         ALOGI("%s: PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN = %d",
893               __FUNCTION__, mPasspointAnqpLen);
894 
895         if (!mPasspointAnqpLen)
896         {
897             break;
898         }
899         mPasspointAnqp = (u8 *) malloc (mPasspointAnqpLen);
900         if (!mPasspointAnqp) {
901             ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
902                   __FUNCTION__);
903             return WIFI_ERROR_OUT_OF_MEMORY;
904         }
905 
906         memset(mPasspointAnqp, 0, mPasspointAnqpLen);
907         if (!
908             tb2[
909                 QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP
910             ])
911             {
912             ALOGE("%s: RESULTS_PASSPOINT_MATCH_ANQP not found", __FUNCTION__);
913             return WIFI_ERROR_INVALID_ARGS;
914         }
915         memcpy(&(mPasspointAnqp[0]),
916                nla_data(tb2[
917                  QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP]),
918                mPasspointAnqpLen);
919 
920         ALOGD("%s: ANQP LEN:%d, ANQP IE:", __FUNCTION__, mPasspointAnqpLen);
921         hexdump((char*)mPasspointAnqp, mPasspointAnqpLen);
922 
923         /* expecting only one result break out after the first loop */
924         break;
925     }
926     return WIFI_SUCCESS;
927 }
928 
gscan_parse_pno_network_results(u32 num_results,wifi_scan_result * results,u32 starting_index,struct nlattr ** tb_vendor)929 wifi_error GScanCommandEventHandler::gscan_parse_pno_network_results(
930                                             u32 num_results,
931                                             wifi_scan_result *results,
932                                             u32 starting_index,
933                                             struct nlattr **tb_vendor)
934 {
935     u32 i = starting_index;
936     struct nlattr *scanResultsInfo;
937     int rem = 0;
938     u32 len = 0;
939     ALOGD("gscan_parse_pno_network_results: starting counter: %d", i);
940 
941     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
942             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
943             rem = nla_len(tb_vendor[
944             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
945             ]);
946                 nla_ok(scanResultsInfo, rem);
947                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
948     {
949         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
950         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
951         (struct nlattr *) nla_data(scanResultsInfo),
952                 nla_len(scanResultsInfo), NULL);
953 
954         if (!
955             tb2[
956                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
957                 ])
958         {
959             ALOGE("gscan_parse_pno_network_results: "
960                 "RESULTS_SCAN_RESULT_TIME_STAMP not found");
961             return WIFI_ERROR_INVALID_ARGS;
962         }
963         results[i].ts =
964             nla_get_u64(
965             tb2[
966                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
967                 ]);
968         if (!
969             tb2[
970                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
971                 ])
972         {
973             ALOGE("gscan_parse_pno_network_results: "
974                 "RESULTS_SCAN_RESULT_SSID not found");
975             return WIFI_ERROR_INVALID_ARGS;
976         }
977         len = nla_len(tb2[
978                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
979         len =
980             sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
981         memcpy((void *)&results[i].ssid,
982             nla_data(
983             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
984         if (!
985             tb2[
986                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
987                 ])
988         {
989             ALOGE("gscan_parse_pno_network_results: "
990                 "RESULTS_SCAN_RESULT_BSSID not found");
991             return WIFI_ERROR_INVALID_ARGS;
992         }
993         len = nla_len(
994             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
995         len =
996             sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
997         memcpy(&results[i].bssid,
998             nla_data(
999             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
1000         if (!
1001             tb2[
1002                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
1003                 ])
1004         {
1005             ALOGE("gscan_parse_pno_network_results: "
1006                 "RESULTS_SCAN_RESULT_CHANNEL not found");
1007             return WIFI_ERROR_INVALID_ARGS;
1008         }
1009         results[i].channel =
1010             nla_get_u32(
1011             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
1012         if (!
1013             tb2[
1014                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
1015                 ])
1016         {
1017             ALOGE("gscan_parse_pno_network_results: "
1018                 "RESULTS_SCAN_RESULT_RSSI not found");
1019             return WIFI_ERROR_INVALID_ARGS;
1020         }
1021         results[i].rssi =
1022             get_s32(
1023             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
1024         if (!
1025             tb2[
1026                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
1027                 ])
1028         {
1029             ALOGE("gscan_parse_pno_network_results: "
1030                 "RESULTS_SCAN_RESULT_RTT not found");
1031             return WIFI_ERROR_INVALID_ARGS;
1032         }
1033         results[i].rtt =
1034             nla_get_u32(
1035             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
1036         if (!
1037             tb2[
1038                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
1039             ])
1040         {
1041             ALOGE("gscan_parse_pno_network_results: "
1042                 "RESULTS_SCAN_RESULT_RTT_SD not found");
1043             return WIFI_ERROR_INVALID_ARGS;
1044         }
1045         results[i].rtt_sd =
1046             nla_get_u32(
1047             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
1048 
1049         if (!
1050             tb2[
1051             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
1052         {
1053             ALOGE("gscan_parse_pno_network_results: "
1054                 "RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
1055                 __FUNCTION__);
1056             return WIFI_ERROR_INVALID_ARGS;
1057             break;
1058         }
1059         results[i].beacon_period =
1060             nla_get_u16(
1061             tb2[
1062             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
1063 
1064         if (!
1065             tb2[
1066                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
1067                 ])
1068         {
1069             ALOGE("gscan_parse_pno_network_results: "
1070                 "RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__);
1071             return WIFI_ERROR_INVALID_ARGS;
1072             break;
1073         }
1074         results[i].capability =
1075             nla_get_u16(
1076             tb2[
1077             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
1078 
1079         ALOGD("gscan_parse_pno_network_results: ts  %lld ", results[i].ts);
1080         ALOGD("gscan_parse_pno_network_results: SSID  %s ",
1081             results[i].ssid) ;
1082         ALOGD("gscan_parse_pno_network_results: "
1083             "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
1084             results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
1085             results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
1086         ALOGD("gscan_parse_pno_network_results: channel %d ",
1087             results[i].channel);
1088         ALOGD("gscan_parse_pno_network_results: rssi %d ", results[i].rssi);
1089         ALOGD("gscan_parse_pno_network_results: rtt %lld ", results[i].rtt);
1090         ALOGD("gscan_parse_pno_network_results: rtt_sd %lld ",
1091             results[i].rtt_sd);
1092         /* Increment loop index for next record */
1093         i++;
1094     }
1095     return WIFI_SUCCESS;
1096 }
1097 
1098 /* This function will be the main handler for incoming (from driver)
1099  * GScan_SUBCMD. Calls the appropriate callback handler after parsing
1100  * the vendor data.
1101  */
handleEvent(WifiEvent & event)1102 int GScanCommandEventHandler::handleEvent(WifiEvent &event)
1103 {
1104     unsigned i=0;
1105     int ret = WIFI_SUCCESS;
1106     u32 status;
1107     wifi_scan_result *result = NULL;
1108     struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
1109 
1110     if (mEventHandlingEnabled == false)
1111     {
1112         ALOGD("%s:Discarding event: %d",
1113               __FUNCTION__, mSubcmd);
1114         return NL_SKIP;
1115     }
1116 
1117     WifiVendorCommand::handleEvent(event);
1118 
1119     nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
1120                         (struct nlattr *)mVendorData,
1121                         mDataLen, NULL);
1122 
1123     switch(mSubcmd)
1124     {
1125         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
1126         {
1127             wifi_request_id reqId;
1128             u32 len = 0;
1129             u32 resultsBufSize = 0;
1130             u32 lengthOfInfoElements = 0;
1131 
1132 #ifdef QC_HAL_DEBUG
1133             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT "
1134                 "received.");
1135 #endif
1136             if (!tbVendor[
1137                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1138             {
1139                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1140                     __FUNCTION__);
1141                 ret = WIFI_ERROR_INVALID_ARGS;
1142                 break;
1143             }
1144             reqId = nla_get_u32(
1145                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1146                     );
1147             /* If event has a different request_id, ignore that and use the
1148              *  request_id value which we're maintaining.
1149              */
1150             if (reqId != mRequestId) {
1151 #ifdef QC_HAL_DEBUG
1152                 ALOGE("%s: Event has Req. ID:%d <> Ours:%d, continue...",
1153                     __FUNCTION__, reqId, mRequestId);
1154 #endif
1155                 reqId = mRequestId;
1156             }
1157 
1158             /* Parse and extract the results. */
1159             if (!
1160                 tbVendor[
1161                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
1162                 ])
1163             {
1164                 ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __FUNCTION__);
1165                 ret = WIFI_ERROR_INVALID_ARGS;
1166                 break;
1167             }
1168             lengthOfInfoElements =
1169                 nla_get_u32(
1170                 tbVendor[
1171                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
1172             ALOGD("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d",
1173                 __FUNCTION__, lengthOfInfoElements);
1174             resultsBufSize =
1175                 lengthOfInfoElements + sizeof(wifi_scan_result);
1176             result = (wifi_scan_result *) malloc (resultsBufSize);
1177             if (!result) {
1178                 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
1179                     __FUNCTION__);
1180                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1181                 break;
1182             }
1183             memset(result, 0, resultsBufSize);
1184 
1185             result->ie_length = lengthOfInfoElements;
1186 
1187             /* Extract and fill out the wifi_scan_result struct. */
1188             if (!
1189             tbVendor[
1190                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
1191                 ])
1192             {
1193                 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
1194                     __FUNCTION__);
1195                 ret = WIFI_ERROR_INVALID_ARGS;
1196                 break;
1197             }
1198             result->ts =
1199                 nla_get_u64(
1200                 tbVendor[
1201                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
1202                     ]);
1203 
1204             if (!
1205                 tbVendor[
1206                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
1207                     ])
1208             {
1209                 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __FUNCTION__);
1210                 ret = WIFI_ERROR_INVALID_ARGS;
1211                 break;
1212             }
1213             len = nla_len(tbVendor[
1214                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
1215             len =
1216                 sizeof(result->ssid) <= len ? sizeof(result->ssid) : len;
1217             memcpy((void *)&result->ssid,
1218                 nla_data(
1219                 tbVendor[
1220                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
1221 
1222             if (!
1223                 tbVendor[
1224                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
1225                     ])
1226             {
1227                 ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __FUNCTION__);
1228                 ret = WIFI_ERROR_INVALID_ARGS;
1229                 break;
1230             }
1231             len = nla_len(
1232                 tbVendor[
1233                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
1234             len =
1235                 sizeof(result->bssid) <= len ? sizeof(result->bssid) : len;
1236             memcpy(&result->bssid,
1237                 nla_data(
1238                 tbVendor[
1239                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
1240 
1241             if (!
1242                 tbVendor[
1243                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
1244                     ])
1245             {
1246                 ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __FUNCTION__);
1247                 ret = WIFI_ERROR_INVALID_ARGS;
1248                 break;
1249             }
1250             result->channel =
1251                 nla_get_u32(
1252                 tbVendor[
1253                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
1254 
1255             if (!
1256                 tbVendor[
1257                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
1258                     ])
1259             {
1260                 ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __FUNCTION__);
1261                 ret = WIFI_ERROR_INVALID_ARGS;
1262                 break;
1263             }
1264             result->rssi =
1265                 get_s32(
1266                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]
1267                 );
1268 
1269             if (!
1270                 tbVendor[
1271                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
1272                     ])
1273             {
1274                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __FUNCTION__);
1275                 ret = WIFI_ERROR_INVALID_ARGS;
1276                 break;
1277             }
1278             result->rtt =
1279                 nla_get_u32(
1280                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
1281 
1282             if (!
1283                 tbVendor[
1284                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
1285                 ])
1286             {
1287                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __FUNCTION__);
1288                 ret = WIFI_ERROR_INVALID_ARGS;
1289                 break;
1290             }
1291             result->rtt_sd =
1292                 nla_get_u32(
1293                 tbVendor[
1294                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
1295 
1296             if (!
1297                 tbVendor[
1298                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
1299             {
1300                 ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
1301                     __FUNCTION__);
1302                 ret = WIFI_ERROR_INVALID_ARGS;
1303                 break;
1304             }
1305             result->beacon_period =
1306                 nla_get_u16(
1307                 tbVendor[
1308                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
1309 
1310             if (!
1311                 tbVendor[
1312                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
1313                     ])
1314             {
1315                 ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__);
1316                 ret = WIFI_ERROR_INVALID_ARGS;
1317                 break;
1318             }
1319             result->capability =
1320                 nla_get_u16(
1321                 tbVendor[
1322                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
1323 
1324             if (!
1325                 tbVendor[
1326                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
1327                 ])
1328             {
1329                 ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __FUNCTION__);
1330                 ret = WIFI_ERROR_INVALID_ARGS;
1331                 break;
1332             }
1333             memcpy(&(result->ie_data[0]),
1334                 nla_data(tbVendor[
1335                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
1336                 lengthOfInfoElements);
1337 #ifdef QC_HAL_DEBUG
1338             ALOGD("handleEvent:FULL_SCAN_RESULTS: ts  %lld ", result->ts);
1339             ALOGD("handleEvent:FULL_SCAN_RESULTS: SSID  %s ", result->ssid) ;
1340             ALOGD("handleEvent:FULL_SCAN_RESULTS: "
1341                 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
1342                 result->bssid[0], result->bssid[1], result->bssid[2],
1343                 result->bssid[3], result->bssid[4], result->bssid[5]);
1344             ALOGD("handleEvent:FULL_SCAN_RESULTS: channel %d ",
1345                 result->channel);
1346             ALOGD("handleEvent:FULL_SCAN_RESULTS: rssi  %d ", result->rssi);
1347             ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt  %lld ", result->rtt);
1348             ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt_sd  %lld ",
1349                 result->rtt_sd);
1350             ALOGD("handleEvent:FULL_SCAN_RESULTS: beacon period  %d ",
1351                 result->beacon_period);
1352             ALOGD("handleEvent:FULL_SCAN_RESULTS: capability  %d ",
1353                 result->capability);
1354             ALOGD("handleEvent:FULL_SCAN_RESULTS: IE length  %d ",
1355                 result->ie_length);
1356 
1357             ALOGD("%s: Invoking the callback. \n", __FUNCTION__);
1358 #endif
1359             if (mHandler.on_full_scan_result) {
1360                 (*mHandler.on_full_scan_result)(reqId, result);
1361                 /* Reset flag and num counter. */
1362                 free(result);
1363                 result = NULL;
1364             }
1365         }
1366         break;
1367 
1368         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
1369         {
1370             wifi_request_id id;
1371             u32 numResults = 0;
1372 
1373             ALOGD("Event "
1374                 "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE "
1375                 "received.");
1376 
1377             if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
1378                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID"
1379                     "not found. Exit", __FUNCTION__);
1380                 ret = WIFI_ERROR_INVALID_ARGS;
1381                 break;
1382             }
1383             id = nla_get_u32(
1384                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1385                     );
1386             /* If this is not for us, then ignore it. */
1387             if (id != mRequestId) {
1388                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1389                     __FUNCTION__, id, mRequestId);
1390                 break;
1391             }
1392             if (!tbVendor[
1393                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1394                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1395                     __FUNCTION__);
1396                 ret = WIFI_ERROR_INVALID_ARGS;
1397                 break;
1398             }
1399             numResults = nla_get_u32(tbVendor[
1400                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1401             ALOGD("%s: number of results:%d", __FUNCTION__, numResults);
1402 
1403             /* Invoke the callback func to report the number of results. */
1404             ALOGD("%s: Calling on_scan_results_available handler",
1405                 __FUNCTION__);
1406             if (!mHandler.on_scan_results_available) {
1407                 break;
1408             }
1409             (*mHandler.on_scan_results_available)(id, numResults);
1410         }
1411         break;
1412 
1413         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
1414         {
1415             wifi_request_id id;
1416             u32 resultsBufSize = 0;
1417             u32 numResults = 0;
1418             u32 startingIndex, sizeOfObtainedResults;
1419 
1420             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND "
1421                 "received.");
1422 
1423             id = nla_get_u32(
1424                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1425                     );
1426             /* If this is not for us, just ignore it. */
1427             if (id != mRequestId) {
1428                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1429                     __FUNCTION__, id, mRequestId);
1430                 break;
1431             }
1432             if (!tbVendor[
1433                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1434                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1435                     __FUNCTION__);
1436                 ret = WIFI_ERROR_INVALID_ARGS;
1437                 break;
1438             }
1439             numResults = nla_get_u32(tbVendor[
1440                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1441             ALOGD("%s: number of results:%d", __FUNCTION__, numResults);
1442 
1443             /* Get the memory size of previous fragments, if any. */
1444             sizeOfObtainedResults = mHotlistApFoundNumResults *
1445                           sizeof(wifi_scan_result);
1446 
1447             mHotlistApFoundNumResults += numResults;
1448             resultsBufSize += mHotlistApFoundNumResults *
1449                                             sizeof(wifi_scan_result);
1450 
1451             /* Check if this chunck of scan results is a continuation of
1452              * a previous one.
1453              */
1454             if (mHotlistApFoundMoreData) {
1455                 mHotlistApFoundResults = (wifi_scan_result *)
1456                             realloc (mHotlistApFoundResults, resultsBufSize);
1457             } else {
1458                 mHotlistApFoundResults = (wifi_scan_result *)
1459                             malloc (resultsBufSize);
1460             }
1461 
1462             if (!mHotlistApFoundResults) {
1463                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1464                     __FUNCTION__);
1465                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1466                 break;
1467             }
1468             /* Initialize the newly allocated memory area with 0. */
1469             memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0,
1470                     resultsBufSize - sizeOfObtainedResults);
1471 
1472             ALOGD("%s: Num of AP FOUND results = %d. \n", __FUNCTION__,
1473                                             mHotlistApFoundNumResults);
1474 
1475             /* To support fragmentation from firmware, monitor the
1476              * MORE_DATA flag and cache results until MORE_DATA = 0.
1477              * Only then we can pass on the results to framework through
1478              * the callback function.
1479              */
1480             if (!tbVendor[
1481                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1482                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1483                     " found", __FUNCTION__);
1484                 ret = WIFI_ERROR_INVALID_ARGS;
1485                 break;
1486             } else {
1487                 mHotlistApFoundMoreData = nla_get_u8(
1488                     tbVendor[
1489                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1490                 ALOGE("%s: More data = %d. \n",
1491                     __FUNCTION__, mHotlistApFoundMoreData);
1492             }
1493 
1494             ALOGD("%s: Extract hotlist_ap_found results.\n", __FUNCTION__);
1495             startingIndex = mHotlistApFoundNumResults - numResults;
1496             ALOGD("%s: starting_index:%d",
1497                 __FUNCTION__, startingIndex);
1498             ret = gscan_parse_hotlist_ap_results(numResults,
1499                                                 mHotlistApFoundResults,
1500                                                 startingIndex,
1501                                                 tbVendor);
1502             /* If a parsing error occurred, exit and proceed for cleanup. */
1503             if (ret)
1504                 break;
1505             /* Send the results if no more result data fragments are expected */
1506             if (!mHotlistApFoundMoreData) {
1507                 (*mHandler.on_hotlist_ap_found)(id,
1508                                                 mHotlistApFoundNumResults,
1509                                                 mHotlistApFoundResults);
1510                 /* Reset flag and num counter. */
1511                 free(mHotlistApFoundResults);
1512                 mHotlistApFoundResults = NULL;
1513                 mHotlistApFoundMoreData = false;
1514                 mHotlistApFoundNumResults = 0;
1515             }
1516         }
1517         break;
1518 
1519         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST:
1520         {
1521             wifi_request_id id;
1522             u32 resultsBufSize = 0;
1523             u32 numResults = 0;
1524             u32 startingIndex, sizeOfObtainedResults;
1525 
1526             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST "
1527                 "received.");
1528 
1529             id = nla_get_u32(
1530                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1531                     );
1532             /* If this is not for us, just ignore it. */
1533             if (id != mRequestId) {
1534                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1535                     __FUNCTION__, id, mRequestId);
1536                 break;
1537             }
1538             if (!tbVendor[
1539                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1540                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1541                     __FUNCTION__);
1542                 ret = WIFI_ERROR_INVALID_ARGS;
1543                 break;
1544             }
1545             numResults = nla_get_u32(tbVendor[
1546                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1547             ALOGD("%s: number of results:%d", __FUNCTION__, numResults);
1548 
1549             /* Get the memory size of previous fragments, if any. */
1550             sizeOfObtainedResults = mHotlistApLostNumResults *
1551                           sizeof(wifi_scan_result);
1552 
1553             mHotlistApLostNumResults += numResults;
1554             resultsBufSize += mHotlistApLostNumResults *
1555                                             sizeof(wifi_scan_result);
1556 
1557             /* Check if this chunck of scan results is a continuation of
1558              * a previous one.
1559              */
1560             if (mHotlistApLostMoreData) {
1561                 mHotlistApLostResults = (wifi_scan_result *)
1562                             realloc (mHotlistApLostResults, resultsBufSize);
1563             } else {
1564                 mHotlistApLostResults = (wifi_scan_result *)
1565                             malloc (resultsBufSize);
1566             }
1567 
1568             if (!mHotlistApLostResults) {
1569                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1570                     __FUNCTION__);
1571                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1572                 break;
1573             }
1574             /* Initialize the newly allocated memory area with 0. */
1575             memset((u8 *)mHotlistApLostResults + sizeOfObtainedResults, 0,
1576                     resultsBufSize - sizeOfObtainedResults);
1577 
1578             ALOGD("%s: Num of AP Lost results = %d. \n", __FUNCTION__,
1579                                             mHotlistApLostNumResults);
1580 
1581             /* To support fragmentation from firmware, monitor the
1582              * MORE_DATA flag and cache results until MORE_DATA = 0.
1583              * Only then we can pass on the results to framework through
1584              * the callback function.
1585              */
1586             if (!tbVendor[
1587                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1588                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1589                     " found", __FUNCTION__);
1590                 ret = WIFI_ERROR_INVALID_ARGS;
1591                 break;
1592             } else {
1593                 mHotlistApLostMoreData = nla_get_u8(
1594                     tbVendor[
1595                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1596                 ALOGE("%s: More data = %d. \n",
1597                     __FUNCTION__, mHotlistApLostMoreData);
1598             }
1599 
1600             ALOGD("%s: Extract hotlist_ap_Lost results.\n", __FUNCTION__);
1601             startingIndex = mHotlistApLostNumResults - numResults;
1602             ALOGD("%s: starting_index:%d",
1603                 __FUNCTION__, startingIndex);
1604             ret = gscan_parse_hotlist_ap_results(numResults,
1605                                                 mHotlistApLostResults,
1606                                                 startingIndex,
1607                                                 tbVendor);
1608             /* If a parsing error occurred, exit and proceed for cleanup. */
1609             if (ret)
1610                 break;
1611             /* Send the results if no more result data fragments are expected */
1612             if (!mHotlistApLostMoreData) {
1613                 (*mHandler.on_hotlist_ap_lost)(id,
1614                                                mHotlistApLostNumResults,
1615                                                mHotlistApLostResults);
1616                 /* Reset flag and num counter. */
1617                 free(mHotlistApLostResults);
1618                 mHotlistApLostResults = NULL;
1619                 mHotlistApLostMoreData = false;
1620                 mHotlistApLostNumResults = 0;
1621             }
1622         }
1623         break;
1624 
1625         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
1626         {
1627             wifi_request_id reqId;
1628             u32 numResults = 0, sizeOfObtainedResults;
1629             u32 startingIndex, index = 0;
1630             struct nlattr *scanResultsInfo;
1631             int rem = 0;
1632 
1633             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE "
1634                 "received.");
1635 
1636             if (!tbVendor[
1637                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1638             {
1639                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1640                     __FUNCTION__);
1641                 ret = WIFI_ERROR_INVALID_ARGS;
1642                 break;
1643             }
1644             reqId = nla_get_u32(
1645                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1646                     );
1647             /* If this is not for us, just ignore it. */
1648             if (reqId != mRequestId) {
1649                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1650                     __FUNCTION__, reqId, mRequestId);
1651                 break;
1652             }
1653             if (!tbVendor[
1654                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE])
1655             {
1656                 ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found."
1657                     "Exit.", __FUNCTION__);
1658                 ret = WIFI_ERROR_INVALID_ARGS;
1659                 break;
1660             }
1661             numResults = nla_get_u32(tbVendor[
1662                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1663             /* Get the memory size of previous fragments, if any. */
1664             sizeOfObtainedResults = sizeof(wifi_significant_change_result *) *
1665                                 mSignificantChangeNumResults;
1666 
1667             index = mSignificantChangeNumResults;
1668             mSignificantChangeNumResults += numResults;
1669             /*
1670              * Check if this chunck of wifi_significant_change results is a
1671              * continuation of a previous one.
1672              */
1673             if (mSignificantChangeMoreData) {
1674                 mSignificantChangeResults =
1675                     (wifi_significant_change_result **)
1676                         realloc (mSignificantChangeResults,
1677                         sizeof(wifi_significant_change_result *) *
1678                                 mSignificantChangeNumResults);
1679             } else {
1680                 mSignificantChangeResults =
1681                     (wifi_significant_change_result **)
1682                         malloc (sizeof(wifi_significant_change_result *) *
1683                                 mSignificantChangeNumResults);
1684             }
1685 
1686             if (!mSignificantChangeResults) {
1687                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1688                     __FUNCTION__);
1689                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1690                 break;
1691             }
1692             /* Initialize the newly allocated memory area with 0. */
1693             memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0,
1694                     sizeof(wifi_significant_change_result *) *
1695                                 numResults);
1696             ALOGD("%s: mSignificantChangeMoreData = %d",
1697                     __FUNCTION__, mSignificantChangeMoreData);
1698 
1699             for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[
1700                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
1701                 rem = nla_len(tbVendor[
1702                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
1703                 nla_ok(scanResultsInfo, rem);
1704                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
1705             {
1706                 u32 num_rssi = 0;
1707                 u32 resultsBufSize = 0;
1708                 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
1709                 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
1710                     (struct nlattr *) nla_data(scanResultsInfo),
1711                     nla_len(scanResultsInfo), NULL);
1712                 if (!tb2[
1713                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
1714                     ])
1715                 {
1716                     ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
1717                         "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. "
1718                         "Exit.", __FUNCTION__);
1719                     ret = WIFI_ERROR_INVALID_ARGS;
1720                     break;
1721                 }
1722                 num_rssi = nla_get_u32(tb2[
1723                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
1724                         ]);
1725                 resultsBufSize = sizeof(wifi_significant_change_result) +
1726                             num_rssi * sizeof(wifi_rssi);
1727                 mSignificantChangeResults[index] =
1728                     (wifi_significant_change_result *) malloc (resultsBufSize);
1729 
1730                 if (!mSignificantChangeResults[index]) {
1731                     ALOGE("%s: Failed to alloc memory for results array Exit",
1732                         __FUNCTION__);
1733                     ret = WIFI_ERROR_OUT_OF_MEMORY;
1734                     break;
1735                 }
1736                 /* Initialize the newly allocated memory area with 0. */
1737                 memset((u8 *)mSignificantChangeResults[index],
1738                         0, resultsBufSize);
1739 
1740                 ALOGD("%s: For Significant Change results[%d], num_rssi:%d\n",
1741                     __FUNCTION__, index, num_rssi);
1742                 index++;
1743             }
1744 
1745             ALOGD("%s: Extract significant change results.\n", __FUNCTION__);
1746             startingIndex =
1747                 mSignificantChangeNumResults - numResults;
1748             ret = gscan_get_significant_change_results(numResults,
1749                                                 mSignificantChangeResults,
1750                                                 startingIndex,
1751                                                 tbVendor);
1752             /* If a parsing error occurred, exit and proceed for cleanup. */
1753             if (ret)
1754                 break;
1755             /* To support fragmentation from firmware, monitor the
1756              * MORE_DATA flag and cache results until MORE_DATA = 0.
1757              * Only then we can pass on the results to framework through
1758              * the callback function.
1759              */
1760             if (!tbVendor[
1761                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1762                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1763                     " found. Stop parsing and exit.", __FUNCTION__);
1764                 break;
1765             }
1766             mSignificantChangeMoreData = nla_get_u8(
1767                 tbVendor[
1768                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1769             ALOGD("%s: More data = %d. \n",
1770                 __FUNCTION__, mSignificantChangeMoreData);
1771 
1772             /* Send the results if no more result fragments are expected */
1773             if (!mSignificantChangeMoreData) {
1774                 ALOGD("%s: Invoking the callback. \n", __FUNCTION__);
1775                 (*mHandler.on_significant_change)(reqId,
1776                                               mSignificantChangeNumResults,
1777                                               mSignificantChangeResults);
1778                 if (mSignificantChangeResults) {
1779                     /* Reset flag and num counter. */
1780                     for (index = 0; index < mSignificantChangeNumResults;
1781                          index++)
1782                     {
1783                         free(mSignificantChangeResults[index]);
1784                         mSignificantChangeResults[index] = NULL;
1785                     }
1786                     free(mSignificantChangeResults);
1787                     mSignificantChangeResults = NULL;
1788                 }
1789                 mSignificantChangeNumResults = 0;
1790                 mSignificantChangeMoreData = false;
1791             }
1792         }
1793         break;
1794 
1795         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
1796         {
1797             wifi_scan_event scanEvent;
1798             u32 scanEventStatus = 0;
1799             wifi_request_id reqId;
1800 
1801             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT "
1802                 "received.");
1803 
1804             if (!tbVendor[
1805                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1806             {
1807                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1808                     __FUNCTION__);
1809                 ret = WIFI_ERROR_INVALID_ARGS;
1810                 break;
1811             }
1812             reqId = nla_get_u32(
1813                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1814                     );
1815             /* If this is not for us, just ignore it. */
1816             if (reqId != mRequestId) {
1817                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1818                     __FUNCTION__, reqId, mRequestId);
1819                 break;
1820             }
1821 
1822             if (!tbVendor[
1823                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) {
1824                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not"
1825                     " found. Stop parsing and exit.", __FUNCTION__);
1826                 break;
1827             }
1828             scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[
1829                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]);
1830 
1831             if (!tbVendor[
1832                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]) {
1833                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_STATUS not"
1834                     " found. Stop parsing and exit.", __FUNCTION__);
1835                 break;
1836             }
1837             scanEventStatus = nla_get_u32(tbVendor[
1838                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]);
1839 
1840             ALOGI("%s: Scan event type: %d, status = %d. \n", __FUNCTION__,
1841                                     scanEvent, scanEventStatus);
1842             /* Send the results if no more result fragments are expected. */
1843             (*mHandler.on_scan_event)(scanEvent, scanEventStatus);
1844         }
1845         break;
1846 
1847         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND:
1848         {
1849             wifi_request_id id;
1850             u32 resultsBufSize = 0;
1851             u32 numResults = 0;
1852             u32 startingIndex, sizeOfObtainedResults;
1853 
1854             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND "
1855                 "received.");
1856 
1857             if (!tbVendor[
1858                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1859             {
1860                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1861                     __FUNCTION__);
1862                 ret = WIFI_ERROR_INVALID_ARGS;
1863                 break;
1864             }
1865 
1866             id = nla_get_u32(
1867                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1868                     );
1869             /* If this is not for us, just ignore it. */
1870             if (id != mRequestId) {
1871                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1872                     __FUNCTION__, id, mRequestId);
1873                 break;
1874             }
1875             if (!tbVendor[
1876                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1877                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1878                     __FUNCTION__);
1879                 ret = WIFI_ERROR_INVALID_ARGS;
1880                 break;
1881             }
1882             numResults = nla_get_u32(tbVendor[
1883                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1884             ALOGD("%s: number of results:%d", __FUNCTION__, numResults);
1885 
1886             /* Get the memory size of previous fragments, if any. */
1887             sizeOfObtainedResults = mHotlistSsidFoundNumResults *
1888                           sizeof(wifi_scan_result);
1889 
1890             mHotlistSsidFoundNumResults += numResults;
1891             resultsBufSize += mHotlistSsidFoundNumResults *
1892                                             sizeof(wifi_scan_result);
1893 
1894             /* Check if this chunck of scan results is a continuation of
1895              * a previous one.
1896              */
1897             if (mHotlistSsidFoundMoreData) {
1898                 mHotlistSsidFoundResults = (wifi_scan_result *)
1899                             realloc (mHotlistSsidFoundResults, resultsBufSize);
1900             } else {
1901                 mHotlistSsidFoundResults = (wifi_scan_result *)
1902                             malloc (resultsBufSize);
1903             }
1904 
1905             if (!mHotlistSsidFoundResults) {
1906                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1907                     __FUNCTION__);
1908                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1909                 break;
1910             }
1911             /* Initialize the newly allocated memory area with 0. */
1912             memset((u8 *)mHotlistSsidFoundResults + sizeOfObtainedResults, 0,
1913                     resultsBufSize - sizeOfObtainedResults);
1914 
1915             ALOGD("%s: Num of SSID FOUND results = %d. \n", __FUNCTION__,
1916                                             mHotlistSsidFoundNumResults);
1917 
1918             /* To support fragmentation from firmware, monitor the
1919              * MORE_DATA flag and cache results until MORE_DATA = 0.
1920              * Only then we can pass on the results to framework through
1921              * the callback function.
1922              */
1923             if (!tbVendor[
1924                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1925                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1926                     " found", __FUNCTION__);
1927                 ret = WIFI_ERROR_INVALID_ARGS;
1928                 break;
1929             } else {
1930                 mHotlistSsidFoundMoreData = nla_get_u8(
1931                     tbVendor[
1932                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1933                 ALOGE("%s: More data = %d. \n",
1934                     __FUNCTION__, mHotlistSsidFoundMoreData);
1935             }
1936 
1937             ALOGD("%s: Extract hotlist_ssid_found results.\n", __FUNCTION__);
1938             startingIndex = mHotlistSsidFoundNumResults - numResults;
1939             ALOGD("%s: starting_index:%d",
1940                 __FUNCTION__, startingIndex);
1941             ret = gscan_parse_hotlist_ssid_results(numResults,
1942                                                 mHotlistSsidFoundResults,
1943                                                 startingIndex,
1944                                                 tbVendor);
1945             /* If a parsing error occurred, exit and proceed for cleanup. */
1946             if (ret)
1947                 break;
1948             /* Send the results if no more result data fragments are expected */
1949             if (!mHotlistSsidFoundMoreData) {
1950                 (*mHandler.on_hotlist_ssid_found)(id,
1951                                                 mHotlistSsidFoundNumResults,
1952                                                 mHotlistSsidFoundResults);
1953                 /* Reset flag and num counter. */
1954                 free(mHotlistSsidFoundResults);
1955                 mHotlistSsidFoundResults = NULL;
1956                 mHotlistSsidFoundMoreData = false;
1957                 mHotlistSsidFoundNumResults = 0;
1958             }
1959         }
1960         break;
1961 
1962         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST:
1963         {
1964             wifi_request_id id;
1965             u32 resultsBufSize = 0;
1966             u32 numResults = 0;
1967             u32 startingIndex, sizeOfObtainedResults;
1968 
1969             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST "
1970                 "received.");
1971 
1972             if (!tbVendor[
1973                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1974             {
1975                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1976                     __FUNCTION__);
1977                 ret = WIFI_ERROR_INVALID_ARGS;
1978                 break;
1979             }
1980 
1981             id = nla_get_u32(
1982                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1983                     );
1984             /* If this is not for us, just ignore it. */
1985             if (id != mRequestId) {
1986                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1987                     __FUNCTION__, id, mRequestId);
1988                 break;
1989             }
1990             if (!tbVendor[
1991                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1992                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1993                     __FUNCTION__);
1994                 ret = WIFI_ERROR_INVALID_ARGS;
1995                 break;
1996             }
1997             numResults = nla_get_u32(tbVendor[
1998                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1999             ALOGD("%s: number of results:%d", __FUNCTION__, numResults);
2000 
2001             /* Get the memory size of previous fragments, if any. */
2002             sizeOfObtainedResults = mHotlistSsidLostNumResults *
2003                           sizeof(wifi_scan_result);
2004 
2005             mHotlistSsidLostNumResults += numResults;
2006             resultsBufSize += mHotlistSsidLostNumResults *
2007                                             sizeof(wifi_scan_result);
2008 
2009             /* Check if this chunck of scan results is a continuation of
2010              * a previous one.
2011              */
2012             if (mHotlistSsidLostMoreData) {
2013                 mHotlistSsidLostResults = (wifi_scan_result *)
2014                             realloc (mHotlistSsidLostResults, resultsBufSize);
2015             } else {
2016                 mHotlistSsidLostResults = (wifi_scan_result *)
2017                             malloc (resultsBufSize);
2018             }
2019 
2020             if (!mHotlistSsidLostResults) {
2021                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
2022                     __FUNCTION__);
2023                 ret = WIFI_ERROR_OUT_OF_MEMORY;
2024                 break;
2025             }
2026             /* Initialize the newly allocated memory area with 0. */
2027             memset((u8 *)mHotlistSsidLostResults + sizeOfObtainedResults, 0,
2028                     resultsBufSize - sizeOfObtainedResults);
2029 
2030             ALOGD("%s: Num of SSID Lost results = %d. \n", __FUNCTION__,
2031                                             mHotlistSsidLostNumResults);
2032 
2033             /* To support fragmentation from firmware, monitor the
2034              * MORE_DATA flag and cache results until MORE_DATA = 0.
2035              * Only then we can pass on the results to framework through
2036              * the callback function.
2037              */
2038             if (!tbVendor[
2039                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
2040                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
2041                     " found", __FUNCTION__);
2042                 ret = WIFI_ERROR_INVALID_ARGS;
2043                 break;
2044             } else {
2045                 mHotlistSsidLostMoreData = nla_get_u8(
2046                     tbVendor[
2047                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
2048                 ALOGE("%s: More data = %d. \n",
2049                     __FUNCTION__, mHotlistSsidLostMoreData);
2050             }
2051 
2052             ALOGD("%s: Extract hotlist_ssid_Lost results.\n", __FUNCTION__);
2053             startingIndex = mHotlistSsidLostNumResults - numResults;
2054             ALOGD("%s: starting_index:%d",
2055                 __FUNCTION__, startingIndex);
2056             ret = gscan_parse_hotlist_ssid_results(numResults,
2057                                                 mHotlistSsidLostResults,
2058                                                 startingIndex,
2059                                                 tbVendor);
2060             /* If a parsing error occurred, exit and proceed for cleanup. */
2061             if (ret)
2062                 break;
2063             /* Send the results if no more result data fragments are expected */
2064             if (!mHotlistSsidLostMoreData) {
2065                 (*mHandler.on_hotlist_ssid_lost)(id,
2066                                                mHotlistSsidLostNumResults,
2067                                                mHotlistSsidLostResults);
2068                 /* Reset flag and num counter. */
2069                 free(mHotlistSsidLostResults);
2070                 mHotlistSsidLostResults = NULL;
2071                 mHotlistSsidLostMoreData = false;
2072                 mHotlistSsidLostNumResults = 0;
2073             }
2074         }
2075         break;
2076 
2077         case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND:
2078         {
2079             wifi_request_id id;
2080             u32 resultsBufSize = 0;
2081             u32 numResults = 0;
2082             u32 startingIndex, sizeOfObtainedResults;
2083 
2084             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND "
2085                 "received.");
2086 
2087             if (!tbVendor[
2088                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
2089             {
2090                 /* RequestId is not provided by FW/Driver for this event */
2091                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.",
2092                     __FUNCTION__);
2093                 id = mRequestId; /* Use the saved mRequestId instead. */
2094             } else {
2095                 id = nla_get_u32(
2096                         tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
2097                         );
2098                 /* If this is not for us, use the saved requestId */
2099                 if (id != mRequestId) {
2100                     ALOGE("%s: Event has Req. ID:%d <> ours:%d",
2101                         __FUNCTION__, id, mRequestId);
2102                     id = mRequestId;
2103                 }
2104             }
2105 
2106             if (!tbVendor[
2107                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
2108                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
2109                     __FUNCTION__);
2110                 ret = WIFI_ERROR_INVALID_ARGS;
2111                 break;
2112             }
2113             numResults = nla_get_u32(tbVendor[
2114                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
2115             ALOGI("%s: number of results:%d", __FUNCTION__, numResults);
2116 
2117             /* Get the memory size of previous fragments, if any. */
2118             sizeOfObtainedResults = mPnoNetworkFoundNumResults *
2119                           sizeof(wifi_scan_result);
2120 
2121             mPnoNetworkFoundNumResults += numResults;
2122             resultsBufSize += mPnoNetworkFoundNumResults *
2123                                             sizeof(wifi_scan_result);
2124 
2125             /* Check if this chunck of scan results is a continuation of
2126              * a previous one.
2127              */
2128             if (mPnoNetworkFoundMoreData) {
2129                 mPnoNetworkFoundResults = (wifi_scan_result *)
2130                             realloc (mPnoNetworkFoundResults, resultsBufSize);
2131             } else {
2132                 mPnoNetworkFoundResults = (wifi_scan_result *)
2133                             malloc (resultsBufSize);
2134             }
2135 
2136             if (!mPnoNetworkFoundResults) {
2137                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
2138                     __FUNCTION__);
2139                 ret = WIFI_ERROR_OUT_OF_MEMORY;
2140                 break;
2141             }
2142             /* Initialize the newly allocated memory area with 0. */
2143             memset((u8 *)mPnoNetworkFoundResults + sizeOfObtainedResults, 0,
2144                     resultsBufSize - sizeOfObtainedResults);
2145 
2146             ALOGI("%s: Num of AP FOUND results = %d. \n", __FUNCTION__,
2147                                             mPnoNetworkFoundNumResults);
2148 
2149             /* To support fragmentation from firmware, monitor the
2150              * MORE_DATA flag and cache results until MORE_DATA = 0.
2151              * Only then we can pass on the results to framework through
2152              * the callback function.
2153              */
2154             if (!tbVendor[
2155                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
2156                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
2157                     " found", __FUNCTION__);
2158                 ret = WIFI_ERROR_INVALID_ARGS;
2159                 break;
2160             } else {
2161                 mPnoNetworkFoundMoreData = nla_get_u8(
2162                     tbVendor[
2163                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
2164                 ALOGD("%s: More data = %d. \n",
2165                     __FUNCTION__, mPnoNetworkFoundMoreData);
2166             }
2167 
2168             ALOGD("%s: Extract PNO_NETWORK_FOUND results.\n", __FUNCTION__);
2169             startingIndex = mPnoNetworkFoundNumResults - numResults;
2170             ALOGD("%s: starting_index:%d",
2171                 __FUNCTION__, startingIndex);
2172             ret = gscan_parse_pno_network_results(numResults,
2173                                                 mPnoNetworkFoundResults,
2174                                                 startingIndex,
2175                                                 tbVendor);
2176             /* If a parsing error occurred, exit and proceed for cleanup. */
2177             if (ret)
2178                 break;
2179             /* Send the results if no more result data fragments are expected */
2180             if (!mPnoNetworkFoundMoreData) {
2181                 (*mHandler.on_pno_network_found)(id,
2182                                                 mPnoNetworkFoundNumResults,
2183                                                 mPnoNetworkFoundResults);
2184                 /* Reset flag and num counter. */
2185                 if (mPnoNetworkFoundResults) {
2186                     free(mPnoNetworkFoundResults);
2187                     mPnoNetworkFoundResults = NULL;
2188                 }
2189                 mPnoNetworkFoundMoreData = false;
2190                 mPnoNetworkFoundNumResults = 0;
2191             }
2192         }
2193         break;
2194         case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND:
2195         {
2196             wifi_request_id id;
2197 
2198             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_"
2199                 "NETWORK_FOUND received.");
2200 
2201             if (!tbVendor[
2202                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
2203             {
2204                 /* RequestId is not provided by FW/Driver for this event */
2205                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.",
2206                     __FUNCTION__);
2207                 id = mRequestId; /* Use the saved mRequestId instead. */
2208             } else {
2209                 id = nla_get_u32(
2210                         tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
2211                         );
2212                 /* If this is not for us, use the saved requestId */
2213                 if (id != mRequestId) {
2214                     ALOGE("%s: Event has Req. ID:%d <> ours:%d",
2215                         __FUNCTION__, id, mRequestId);
2216                     id = mRequestId;
2217                 }
2218             }
2219 
2220             ret = gscan_parse_passpoint_network_result(tbVendor);
2221             /* If a parsing error occurred, exit and proceed for cleanup. */
2222             if (ret)
2223             {
2224                 ALOGE("%s: gscan_parse_passpoint_network_result"
2225                       "returned error: %d.\n", __FUNCTION__, ret);
2226                 break;
2227             }
2228             (*mHandler.on_passpoint_network_found)(id,
2229                                                    mPasspointNetId,
2230                                                    mPasspointNetworkFoundResult,
2231                                                    mPasspointAnqpLen,
2232                                                    mPasspointAnqp);
2233             if (mPasspointNetworkFoundResult)
2234             {
2235                 free(mPasspointNetworkFoundResult);
2236                 mPasspointNetworkFoundResult = NULL;
2237             }
2238             if (mPasspointAnqp)
2239             {
2240                 free(mPasspointAnqp);
2241                 mPasspointAnqp = NULL;
2242             }
2243             mPasspointNetId = -1;
2244             mPasspointAnqpLen = 0;
2245         }
2246         break;
2247         default:
2248             /* Error case should not happen print log */
2249             ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd);
2250     }
2251 
2252     /* A parsing error occurred, do the cleanup of gscan result lists. */
2253     if (ret) {
2254         switch(mSubcmd)
2255         {
2256             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
2257             {
2258                 free(result);
2259                 result = NULL;
2260             }
2261             break;
2262 
2263             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
2264             {
2265                 /* Reset flag and num counter. */
2266                 free(mHotlistApFoundResults);
2267                 mHotlistApFoundResults = NULL;
2268                 mHotlistApFoundMoreData = false;
2269                 mHotlistApFoundNumResults = 0;
2270             }
2271             break;
2272 
2273             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
2274             {
2275                 if (mSignificantChangeResults) {
2276                     for (i = 0; i < mSignificantChangeNumResults; i++)
2277                     {
2278                         if (mSignificantChangeResults[i]) {
2279                             free(mSignificantChangeResults[i]);
2280                             mSignificantChangeResults[i] = NULL;
2281                         }
2282                     }
2283                     free(mSignificantChangeResults);
2284                     mSignificantChangeResults = NULL;
2285                 }
2286                 mSignificantChangeNumResults = 0;
2287                 mSignificantChangeMoreData = false;
2288             }
2289             break;
2290 
2291             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
2292             break;
2293 
2294             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
2295             break;
2296 
2297             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST:
2298             {
2299                 /* Reset flag and num counter. */
2300                 free(mHotlistApLostResults);
2301                 mHotlistApLostResults = NULL;
2302                 mHotlistApLostMoreData = false;
2303                 mHotlistApLostNumResults = 0;
2304             }
2305             break;
2306 
2307             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND:
2308             {
2309                 /* Reset flag and num counter. */
2310                 free(mHotlistSsidFoundResults);
2311                 mHotlistSsidFoundResults = NULL;
2312                 mHotlistSsidFoundMoreData = false;
2313                 mHotlistSsidFoundNumResults = 0;
2314             }
2315             break;
2316             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST:
2317             {
2318                 /* Reset flag and num counter. */
2319                 free(mHotlistSsidLostResults);
2320                 mHotlistSsidLostResults = NULL;
2321                 mHotlistSsidLostMoreData = false;
2322                 mHotlistSsidLostNumResults = 0;
2323             }
2324             break;
2325 
2326             case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND:
2327             {
2328                 /* Reset flag and num counter. */
2329                 if (mPnoNetworkFoundResults) {
2330                     free(mPnoNetworkFoundResults);
2331                     mPnoNetworkFoundResults = NULL;
2332                 }
2333                 mPnoNetworkFoundMoreData = false;
2334                 mPnoNetworkFoundNumResults = 0;
2335             }
2336             break;
2337 
2338             case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND:
2339             {
2340                 if (mPasspointNetworkFoundResult)
2341                 {
2342                     free(mPasspointNetworkFoundResult);
2343                     mPasspointNetworkFoundResult = NULL;
2344                 }
2345                 if (mPasspointAnqp)
2346                 {
2347                     free(mPasspointAnqp);
2348                     mPasspointAnqp = NULL;
2349                 }
2350                 mPasspointNetId = -1;
2351                 mPasspointAnqpLen = 0;
2352             }
2353             break;
2354 
2355             default:
2356                 ALOGE("%s: Parsing err handler: wrong GScan subcmd "
2357                     "received %d", __FUNCTION__, mSubcmd);
2358         }
2359     }
2360     return NL_SKIP;
2361 }
2362