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