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