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     wifi_scan_result *result = NULL;
1045     struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
1046 
1047     if (mEventHandlingEnabled == false)
1048     {
1049         ALOGV("%s:Discarding event: %d",
1050               __FUNCTION__, mSubcmd);
1051         return NL_SKIP;
1052     }
1053 
1054     WifiVendorCommand::handleEvent(event);
1055 
1056     nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
1057                         (struct nlattr *)mVendorData,
1058                         mDataLen, NULL);
1059 
1060     switch(mSubcmd)
1061     {
1062         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
1063         {
1064             wifi_request_id reqId;
1065             u32 len = 0;
1066             u32 resultsBufSize = 0;
1067             u32 lengthOfInfoElements = 0;
1068             u32 buckets_scanned = 0;
1069 
1070             ALOGV("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT "
1071                 "received.");
1072             if (!tbVendor[
1073                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1074             {
1075                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1076                     __FUNCTION__);
1077                 ret = WIFI_ERROR_INVALID_ARGS;
1078                 break;
1079             }
1080             reqId = nla_get_u32(
1081                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1082                     );
1083             /* If event has a different request_id, ignore that and use the
1084              *  request_id value which we're maintaining.
1085              */
1086             if (reqId != mRequestId) {
1087 #ifdef QC_HAL_DEBUG
1088                 ALOGE("%s: Event has Req. ID:%d <> Ours:%d, continue...",
1089                     __FUNCTION__, reqId, mRequestId);
1090 #endif
1091                 reqId = mRequestId;
1092             }
1093 
1094             /* Parse and extract the results. */
1095             if (!
1096                 tbVendor[
1097                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
1098                 ])
1099             {
1100                 ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __FUNCTION__);
1101                 ret = WIFI_ERROR_INVALID_ARGS;
1102                 break;
1103             }
1104             lengthOfInfoElements =
1105                 nla_get_u32(
1106                 tbVendor[
1107                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
1108 
1109             ALOGV("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d",
1110                 __FUNCTION__, lengthOfInfoElements);
1111 
1112             resultsBufSize =
1113                 lengthOfInfoElements + sizeof(wifi_scan_result);
1114             result = (wifi_scan_result *) malloc (resultsBufSize);
1115             if (!result) {
1116                 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
1117                     __FUNCTION__);
1118                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1119                 break;
1120             }
1121             memset(result, 0, resultsBufSize);
1122 
1123             result->ie_length = lengthOfInfoElements;
1124 
1125             /* Extract and fill out the wifi_scan_result struct. */
1126             if (!
1127             tbVendor[
1128                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
1129                 ])
1130             {
1131                 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
1132                     __FUNCTION__);
1133                 ret = WIFI_ERROR_INVALID_ARGS;
1134                 break;
1135             }
1136             result->ts =
1137                 nla_get_u64(
1138                 tbVendor[
1139                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
1140                     ]);
1141 
1142             if (!
1143                 tbVendor[
1144                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
1145                     ])
1146             {
1147                 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __FUNCTION__);
1148                 ret = WIFI_ERROR_INVALID_ARGS;
1149                 break;
1150             }
1151             len = nla_len(tbVendor[
1152                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
1153             len =
1154                 sizeof(result->ssid) <= len ? sizeof(result->ssid) : len;
1155             memcpy((void *)&result->ssid,
1156                 nla_data(
1157                 tbVendor[
1158                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
1159 
1160             if (!
1161                 tbVendor[
1162                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
1163                     ])
1164             {
1165                 ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __FUNCTION__);
1166                 ret = WIFI_ERROR_INVALID_ARGS;
1167                 break;
1168             }
1169             len = nla_len(
1170                 tbVendor[
1171                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
1172             len =
1173                 sizeof(result->bssid) <= len ? sizeof(result->bssid) : len;
1174             memcpy(&result->bssid,
1175                 nla_data(
1176                 tbVendor[
1177                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
1178 
1179             if (!
1180                 tbVendor[
1181                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
1182                     ])
1183             {
1184                 ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __FUNCTION__);
1185                 ret = WIFI_ERROR_INVALID_ARGS;
1186                 break;
1187             }
1188             result->channel =
1189                 nla_get_u32(
1190                 tbVendor[
1191                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
1192 
1193             if (!
1194                 tbVendor[
1195                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
1196                     ])
1197             {
1198                 ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __FUNCTION__);
1199                 ret = WIFI_ERROR_INVALID_ARGS;
1200                 break;
1201             }
1202             result->rssi =
1203                 get_s32(
1204                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]
1205                 );
1206 
1207             if (!
1208                 tbVendor[
1209                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
1210                     ])
1211             {
1212                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __FUNCTION__);
1213                 ret = WIFI_ERROR_INVALID_ARGS;
1214                 break;
1215             }
1216             result->rtt =
1217                 nla_get_u32(
1218                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
1219 
1220             if (!
1221                 tbVendor[
1222                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
1223                 ])
1224             {
1225                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __FUNCTION__);
1226                 ret = WIFI_ERROR_INVALID_ARGS;
1227                 break;
1228             }
1229             result->rtt_sd =
1230                 nla_get_u32(
1231                 tbVendor[
1232                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
1233 
1234             if (!
1235                 tbVendor[
1236                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
1237             {
1238                 ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
1239                     __FUNCTION__);
1240                 ret = WIFI_ERROR_INVALID_ARGS;
1241                 break;
1242             }
1243             result->beacon_period =
1244                 nla_get_u16(
1245                 tbVendor[
1246                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
1247 
1248             if (!
1249                 tbVendor[
1250                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
1251                     ])
1252             {
1253                 ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__);
1254                 ret = WIFI_ERROR_INVALID_ARGS;
1255                 break;
1256             }
1257             result->capability =
1258                 nla_get_u16(
1259                 tbVendor[
1260                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
1261 
1262             if (!
1263                 tbVendor[
1264                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
1265                 ])
1266             {
1267                 ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __FUNCTION__);
1268                 ret = WIFI_ERROR_INVALID_ARGS;
1269                 break;
1270             }
1271             memcpy(&(result->ie_data[0]),
1272                 nla_data(tbVendor[
1273                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
1274                 lengthOfInfoElements);
1275             if (!
1276                 tbVendor[
1277                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED
1278                     ])
1279             {
1280                 ALOGD("%s: RESULTS_BUCKETS_SCANNED not found", __FUNCTION__);
1281             } else {
1282                 buckets_scanned = get_u32(tbVendor[
1283                            QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]);
1284             }
1285 #ifdef QC_HAL_DEBUG
1286             ALOGD("handleEvent:FULL_SCAN_RESULTS: ts  %" PRId64, result->ts);
1287             ALOGD("handleEvent:FULL_SCAN_RESULTS: SSID  %s ", result->ssid) ;
1288             ALOGD("handleEvent:FULL_SCAN_RESULTS: "
1289                 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
1290                 result->bssid[0], result->bssid[1], result->bssid[2],
1291                 result->bssid[3], result->bssid[4], result->bssid[5]);
1292             ALOGD("handleEvent:FULL_SCAN_RESULTS: channel %d ",
1293                 result->channel);
1294             ALOGD("handleEvent:FULL_SCAN_RESULTS: rssi  %d ", result->rssi);
1295             ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt  %" PRId64, result->rtt);
1296             ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt_sd  %" PRId64,
1297                 result->rtt_sd);
1298             ALOGD("handleEvent:FULL_SCAN_RESULTS: beacon period  %d ",
1299                 result->beacon_period);
1300             ALOGD("handleEvent:FULL_SCAN_RESULTS: capability  %d ",
1301                 result->capability);
1302             ALOGD("handleEvent:FULL_SCAN_RESULTS: IE length  %d ",
1303                 result->ie_length);
1304 
1305             ALOGD("%s: Invoking the callback. \n", __FUNCTION__);
1306 #endif
1307             if (mHandler.on_full_scan_result) {
1308                 (*mHandler.on_full_scan_result)(reqId, result, buckets_scanned);
1309                 /* Reset flag and num counter. */
1310                 free(result);
1311                 result = NULL;
1312             }
1313         }
1314         break;
1315 
1316         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
1317         {
1318             wifi_request_id id;
1319 
1320 #ifdef QC_HAL_DEBUG
1321             ALOGV("Event "
1322                     "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE "
1323                     "received.");
1324 #endif
1325 
1326             if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
1327                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID"
1328                         "not found. Exit", __FUNCTION__);
1329                 ret = WIFI_ERROR_INVALID_ARGS;
1330                 break;
1331             }
1332             id = nla_get_u32(
1333                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1334                              );
1335             /* If this is not for us, then ignore it. */
1336             if (id != mRequestId) {
1337                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1338                         __FUNCTION__, id, mRequestId);
1339                 break;
1340             }
1341 
1342             /* Invoke the callback func to report the number of results. */
1343             ALOGV("%s: Calling on_scan_event handler", __FUNCTION__);
1344             (*mHandler.on_scan_event)(id, WIFI_SCAN_THRESHOLD_NUM_SCANS);
1345         }
1346         break;
1347 
1348         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
1349         {
1350             wifi_request_id id;
1351             u32 resultsBufSize = 0;
1352             u32 numResults = 0;
1353             u32 startingIndex, sizeOfObtainedResults;
1354 
1355             id = nla_get_u32(
1356                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1357                     );
1358             /* If this is not for us, just ignore it. */
1359             if (id != mRequestId) {
1360                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1361                     __FUNCTION__, id, mRequestId);
1362                 break;
1363             }
1364             if (!tbVendor[
1365                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1366                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1367                     __FUNCTION__);
1368                 ret = WIFI_ERROR_INVALID_ARGS;
1369                 break;
1370             }
1371             numResults = nla_get_u32(tbVendor[
1372                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1373             ALOGV("%s: number of results:%d", __FUNCTION__, numResults);
1374 
1375             /* Get the memory size of previous fragments, if any. */
1376             sizeOfObtainedResults = mHotlistApFoundNumResults *
1377                           sizeof(wifi_scan_result);
1378 
1379             mHotlistApFoundNumResults += numResults;
1380             resultsBufSize += mHotlistApFoundNumResults *
1381                                             sizeof(wifi_scan_result);
1382 
1383             /* Check if this chunck of scan results is a continuation of
1384              * a previous one.
1385              */
1386             if (mHotlistApFoundMoreData) {
1387                 mHotlistApFoundResults = (wifi_scan_result *)
1388                             realloc (mHotlistApFoundResults, resultsBufSize);
1389             } else {
1390                 mHotlistApFoundResults = (wifi_scan_result *)
1391                             malloc (resultsBufSize);
1392             }
1393 
1394             if (!mHotlistApFoundResults) {
1395                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1396                     __FUNCTION__);
1397                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1398                 break;
1399             }
1400             /* Initialize the newly allocated memory area with 0. */
1401             memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0,
1402                     resultsBufSize - sizeOfObtainedResults);
1403 
1404             ALOGV("%s: Num of AP FOUND results = %d. \n", __FUNCTION__,
1405                                             mHotlistApFoundNumResults);
1406 
1407             /* To support fragmentation from firmware, monitor the
1408              * MORE_DATA flag and cache results until MORE_DATA = 0.
1409              * Only then we can pass on the results to framework through
1410              * the callback function.
1411              */
1412             if (!tbVendor[
1413                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1414                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1415                     " found", __FUNCTION__);
1416                 ret = WIFI_ERROR_INVALID_ARGS;
1417                 break;
1418             } else {
1419                 mHotlistApFoundMoreData = nla_get_u8(
1420                     tbVendor[
1421                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1422                 ALOGE("%s: More data = %d. \n",
1423                     __FUNCTION__, mHotlistApFoundMoreData);
1424             }
1425 
1426             ALOGV("%s: Extract hotlist_ap_found results.\n", __FUNCTION__);
1427             startingIndex = mHotlistApFoundNumResults - numResults;
1428             ALOGV("%s: starting_index:%d",
1429                 __FUNCTION__, startingIndex);
1430             ret = gscan_parse_hotlist_ap_results(numResults,
1431                                                 mHotlistApFoundResults,
1432                                                 startingIndex,
1433                                                 tbVendor);
1434             /* If a parsing error occurred, exit and proceed for cleanup. */
1435             if (ret)
1436                 break;
1437             /* Send the results if no more result data fragments are expected */
1438             if (!mHotlistApFoundMoreData) {
1439                 (*mHandler.on_hotlist_ap_found)(id,
1440                                                 mHotlistApFoundNumResults,
1441                                                 mHotlistApFoundResults);
1442                 /* Reset flag and num counter. */
1443                 free(mHotlistApFoundResults);
1444                 mHotlistApFoundResults = NULL;
1445                 mHotlistApFoundMoreData = false;
1446                 mHotlistApFoundNumResults = 0;
1447             }
1448         }
1449         break;
1450 
1451         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST:
1452         {
1453             wifi_request_id id;
1454             u32 resultsBufSize = 0;
1455             u32 numResults = 0;
1456             u32 startingIndex, sizeOfObtainedResults;
1457 
1458             id = nla_get_u32(
1459                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1460                     );
1461             /* If this is not for us, just ignore it. */
1462             if (id != mRequestId) {
1463                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1464                     __FUNCTION__, id, mRequestId);
1465                 break;
1466             }
1467             if (!tbVendor[
1468                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1469                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1470                     __FUNCTION__);
1471                 ret = WIFI_ERROR_INVALID_ARGS;
1472                 break;
1473             }
1474             numResults = nla_get_u32(tbVendor[
1475                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1476             ALOGV("%s: number of results:%d", __FUNCTION__, numResults);
1477 
1478             /* Get the memory size of previous fragments, if any. */
1479             sizeOfObtainedResults = mHotlistApLostNumResults *
1480                           sizeof(wifi_scan_result);
1481 
1482             mHotlistApLostNumResults += numResults;
1483             resultsBufSize += mHotlistApLostNumResults *
1484                                             sizeof(wifi_scan_result);
1485 
1486             /* Check if this chunck of scan results is a continuation of
1487              * a previous one.
1488              */
1489             if (mHotlistApLostMoreData) {
1490                 mHotlistApLostResults = (wifi_scan_result *)
1491                             realloc (mHotlistApLostResults, resultsBufSize);
1492             } else {
1493                 mHotlistApLostResults = (wifi_scan_result *)
1494                             malloc (resultsBufSize);
1495             }
1496 
1497             if (!mHotlistApLostResults) {
1498                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1499                     __FUNCTION__);
1500                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1501                 break;
1502             }
1503             /* Initialize the newly allocated memory area with 0. */
1504             memset((u8 *)mHotlistApLostResults + sizeOfObtainedResults, 0,
1505                     resultsBufSize - sizeOfObtainedResults);
1506 
1507             ALOGV("%s: Num of AP Lost results = %d. \n", __FUNCTION__,
1508                                             mHotlistApLostNumResults);
1509 
1510             /* To support fragmentation from firmware, monitor the
1511              * MORE_DATA flag and cache results until MORE_DATA = 0.
1512              * Only then we can pass on the results to framework through
1513              * the callback function.
1514              */
1515             if (!tbVendor[
1516                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1517                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1518                     " found", __FUNCTION__);
1519                 ret = WIFI_ERROR_INVALID_ARGS;
1520                 break;
1521             } else {
1522                 mHotlistApLostMoreData = nla_get_u8(
1523                     tbVendor[
1524                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1525                 ALOGV("%s: More data = %d. \n",
1526                     __FUNCTION__, mHotlistApLostMoreData);
1527             }
1528 
1529             ALOGV("%s: Extract hotlist_ap_Lost results.\n", __FUNCTION__);
1530             startingIndex = mHotlistApLostNumResults - numResults;
1531             ALOGV("%s: starting_index:%d",
1532                 __FUNCTION__, startingIndex);
1533             ret = gscan_parse_hotlist_ap_results(numResults,
1534                                                 mHotlistApLostResults,
1535                                                 startingIndex,
1536                                                 tbVendor);
1537             /* If a parsing error occurred, exit and proceed for cleanup. */
1538             if (ret)
1539                 break;
1540             /* Send the results if no more result data fragments are expected */
1541             if (!mHotlistApLostMoreData) {
1542                 (*mHandler.on_hotlist_ap_lost)(id,
1543                                                mHotlistApLostNumResults,
1544                                                mHotlistApLostResults);
1545                 /* Reset flag and num counter. */
1546                 free(mHotlistApLostResults);
1547                 mHotlistApLostResults = NULL;
1548                 mHotlistApLostMoreData = false;
1549                 mHotlistApLostNumResults = 0;
1550             }
1551         }
1552         break;
1553 
1554         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
1555         {
1556             wifi_request_id reqId;
1557             u32 numResults = 0, sizeOfObtainedResults;
1558             u32 startingIndex, index = 0;
1559             struct nlattr *scanResultsInfo;
1560             int rem = 0;
1561 
1562             if (!tbVendor[
1563                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1564             {
1565                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1566                     __FUNCTION__);
1567                 ret = WIFI_ERROR_INVALID_ARGS;
1568                 break;
1569             }
1570             reqId = nla_get_u32(
1571                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1572                     );
1573             /* If this is not for us, just ignore it. */
1574             if (reqId != mRequestId) {
1575                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1576                     __FUNCTION__, reqId, mRequestId);
1577                 break;
1578             }
1579             if (!tbVendor[
1580                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE])
1581             {
1582                 ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found."
1583                     "Exit.", __FUNCTION__);
1584                 ret = WIFI_ERROR_INVALID_ARGS;
1585                 break;
1586             }
1587             numResults = nla_get_u32(tbVendor[
1588                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1589             /* Get the memory size of previous fragments, if any. */
1590             sizeOfObtainedResults = sizeof(wifi_significant_change_result *) *
1591                                 mSignificantChangeNumResults;
1592 
1593             index = mSignificantChangeNumResults;
1594             mSignificantChangeNumResults += numResults;
1595             /*
1596              * Check if this chunck of wifi_significant_change results is a
1597              * continuation of a previous one.
1598              */
1599             if (mSignificantChangeMoreData) {
1600                 mSignificantChangeResults =
1601                     (wifi_significant_change_result **)
1602                         realloc (mSignificantChangeResults,
1603                         sizeof(wifi_significant_change_result *) *
1604                                 mSignificantChangeNumResults);
1605             } else {
1606                 mSignificantChangeResults =
1607                     (wifi_significant_change_result **)
1608                         malloc (sizeof(wifi_significant_change_result *) *
1609                                 mSignificantChangeNumResults);
1610             }
1611 
1612             if (!mSignificantChangeResults) {
1613                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1614                     __FUNCTION__);
1615                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1616                 break;
1617             }
1618             /* Initialize the newly allocated memory area with 0. */
1619             memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0,
1620                     sizeof(wifi_significant_change_result *) *
1621                                 numResults);
1622             ALOGV("%s: mSignificantChangeMoreData = %d",
1623                     __FUNCTION__, mSignificantChangeMoreData);
1624 
1625             for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[
1626                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
1627                 rem = nla_len(tbVendor[
1628                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
1629                 nla_ok(scanResultsInfo, rem);
1630                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
1631             {
1632                 u32 num_rssi = 0;
1633                 u32 resultsBufSize = 0;
1634                 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
1635                 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
1636                     (struct nlattr *) nla_data(scanResultsInfo),
1637                     nla_len(scanResultsInfo), NULL);
1638                 if (!tb2[
1639                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
1640                     ])
1641                 {
1642                     ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
1643                         "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. "
1644                         "Exit.", __FUNCTION__);
1645                     ret = WIFI_ERROR_INVALID_ARGS;
1646                     break;
1647                 }
1648                 num_rssi = nla_get_u32(tb2[
1649                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
1650                         ]);
1651                 resultsBufSize = sizeof(wifi_significant_change_result) +
1652                             num_rssi * sizeof(wifi_rssi);
1653                 mSignificantChangeResults[index] =
1654                     (wifi_significant_change_result *) malloc (resultsBufSize);
1655 
1656                 if (!mSignificantChangeResults[index]) {
1657                     ALOGE("%s: Failed to alloc memory for results array Exit",
1658                         __FUNCTION__);
1659                     ret = WIFI_ERROR_OUT_OF_MEMORY;
1660                     break;
1661                 }
1662                 /* Initialize the newly allocated memory area with 0. */
1663                 memset((u8 *)mSignificantChangeResults[index],
1664                         0, resultsBufSize);
1665 
1666                 ALOGV("%s: For Significant Change results[%d], num_rssi:%d\n",
1667                     __FUNCTION__, index, num_rssi);
1668                 index++;
1669             }
1670 
1671             ALOGV("%s: Extract significant change results.\n", __FUNCTION__);
1672             startingIndex =
1673                 mSignificantChangeNumResults - numResults;
1674             ret = gscan_get_significant_change_results(numResults,
1675                                                 mSignificantChangeResults,
1676                                                 startingIndex,
1677                                                 tbVendor);
1678             /* If a parsing error occurred, exit and proceed for cleanup. */
1679             if (ret)
1680                 break;
1681             /* To support fragmentation from firmware, monitor the
1682              * MORE_DATA flag and cache results until MORE_DATA = 0.
1683              * Only then we can pass on the results to framework through
1684              * the callback function.
1685              */
1686             if (!tbVendor[
1687                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1688                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1689                     " found. Stop parsing and exit.", __FUNCTION__);
1690                 break;
1691             }
1692             mSignificantChangeMoreData = nla_get_u8(
1693                 tbVendor[
1694                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1695             ALOGV("%s: More data = %d. \n",
1696                 __FUNCTION__, mSignificantChangeMoreData);
1697 
1698             /* Send the results if no more result fragments are expected */
1699             if (!mSignificantChangeMoreData) {
1700                 ALOGV("%s: Invoking the callback. \n", __FUNCTION__);
1701                 (*mHandler.on_significant_change)(reqId,
1702                                               mSignificantChangeNumResults,
1703                                               mSignificantChangeResults);
1704                 if (mSignificantChangeResults) {
1705                     /* Reset flag and num counter. */
1706                     for (index = 0; index < mSignificantChangeNumResults;
1707                          index++)
1708                     {
1709                         free(mSignificantChangeResults[index]);
1710                         mSignificantChangeResults[index] = NULL;
1711                     }
1712                     free(mSignificantChangeResults);
1713                     mSignificantChangeResults = NULL;
1714                 }
1715                 mSignificantChangeNumResults = 0;
1716                 mSignificantChangeMoreData = false;
1717             }
1718         }
1719         break;
1720 
1721         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
1722         {
1723             wifi_scan_event scanEvent;
1724             wifi_request_id reqId;
1725 
1726             if (!tbVendor[
1727                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1728             {
1729                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1730                     __FUNCTION__);
1731                 ret = WIFI_ERROR_INVALID_ARGS;
1732                 break;
1733             }
1734             reqId = nla_get_u32(
1735                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1736                     );
1737             /* If this is not for us, just ignore it. */
1738             if (reqId != mRequestId) {
1739                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1740                     __FUNCTION__, reqId, mRequestId);
1741                 break;
1742             }
1743 
1744             if (!tbVendor[
1745                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) {
1746                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not"
1747                     " found. Stop parsing and exit.", __FUNCTION__);
1748                 break;
1749             }
1750             scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[
1751                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]);
1752 
1753             ALOGV("%s: Scan event type: %d\n", __FUNCTION__, scanEvent);
1754             /* Send the results if no more result fragments are expected. */
1755             (*mHandler.on_scan_event)(reqId, scanEvent);
1756         }
1757         break;
1758 
1759         case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND:
1760         {
1761             wifi_request_id id;
1762             u32 resultsBufSize = 0;
1763             u32 numResults = 0;
1764             u32 startingIndex, sizeOfObtainedResults;
1765 
1766             if (!tbVendor[
1767                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1768             {
1769                 /* RequestId is not provided by FW/Driver for this event */
1770                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.",
1771                     __FUNCTION__);
1772                 id = mRequestId; /* Use the saved mRequestId instead. */
1773             } else {
1774                 id = nla_get_u32(
1775                         tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1776                         );
1777                 /* If this is not for us, use the saved requestId */
1778                 if (id != mRequestId) {
1779                     ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1780                         __FUNCTION__, id, mRequestId);
1781                     id = mRequestId;
1782                 }
1783             }
1784 
1785             if (!tbVendor[
1786                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1787                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1788                     __FUNCTION__);
1789                 ret = WIFI_ERROR_INVALID_ARGS;
1790                 break;
1791             }
1792             numResults = nla_get_u32(tbVendor[
1793                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1794             ALOGV("%s: number of results:%d", __FUNCTION__, numResults);
1795 
1796             /* Get the memory size of previous fragments, if any. */
1797             sizeOfObtainedResults = mPnoNetworkFoundNumResults *
1798                           sizeof(wifi_scan_result);
1799 
1800             mPnoNetworkFoundNumResults += numResults;
1801             resultsBufSize += mPnoNetworkFoundNumResults *
1802                                             sizeof(wifi_scan_result);
1803 
1804             /* Check if this chunck of scan results is a continuation of
1805              * a previous one.
1806              */
1807             if (mPnoNetworkFoundMoreData) {
1808                 mPnoNetworkFoundResults = (wifi_scan_result *)
1809                             realloc (mPnoNetworkFoundResults, resultsBufSize);
1810             } else {
1811                 mPnoNetworkFoundResults = (wifi_scan_result *)
1812                             malloc (resultsBufSize);
1813             }
1814 
1815             if (!mPnoNetworkFoundResults) {
1816                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1817                     __FUNCTION__);
1818                 ret = WIFI_ERROR_OUT_OF_MEMORY;
1819                 break;
1820             }
1821             /* Initialize the newly allocated memory area with 0. */
1822             memset((u8 *)mPnoNetworkFoundResults + sizeOfObtainedResults, 0,
1823                     resultsBufSize - sizeOfObtainedResults);
1824 
1825             ALOGV("%s: Num of AP FOUND results = %d. \n", __FUNCTION__,
1826                                             mPnoNetworkFoundNumResults);
1827 
1828             /* To support fragmentation from firmware, monitor the
1829              * MORE_DATA flag and cache results until MORE_DATA = 0.
1830              * Only then we can pass on the results to framework through
1831              * the callback function.
1832              */
1833             if (!tbVendor[
1834                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1835                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1836                     " found", __FUNCTION__);
1837                 ret = WIFI_ERROR_INVALID_ARGS;
1838                 break;
1839             } else {
1840                 mPnoNetworkFoundMoreData = nla_get_u8(
1841                     tbVendor[
1842                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1843                 ALOGV("%s: More data = %d. \n",
1844                     __FUNCTION__, mPnoNetworkFoundMoreData);
1845             }
1846 
1847             ALOGV("%s: Extract PNO_NETWORK_FOUND results.\n", __FUNCTION__);
1848             startingIndex = mPnoNetworkFoundNumResults - numResults;
1849             ALOGV("%s: starting_index:%d",
1850                 __FUNCTION__, startingIndex);
1851             ret = gscan_parse_pno_network_results(numResults,
1852                                                 mPnoNetworkFoundResults,
1853                                                 startingIndex,
1854                                                 tbVendor);
1855             /* If a parsing error occurred, exit and proceed for cleanup. */
1856             if (ret)
1857                 break;
1858             /* Send the results if no more result data fragments are expected */
1859             if (!mPnoNetworkFoundMoreData) {
1860                 (*mHandler.on_pno_network_found)(id,
1861                                                 mPnoNetworkFoundNumResults,
1862                                                 mPnoNetworkFoundResults);
1863                 /* Reset flag and num counter. */
1864                 if (mPnoNetworkFoundResults) {
1865                     free(mPnoNetworkFoundResults);
1866                     mPnoNetworkFoundResults = NULL;
1867                 }
1868                 mPnoNetworkFoundMoreData = false;
1869                 mPnoNetworkFoundNumResults = 0;
1870             }
1871         }
1872         break;
1873         case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND:
1874         {
1875             wifi_request_id id;
1876 
1877             if (!tbVendor[
1878                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1879             {
1880                 /* RequestId is not provided by FW/Driver for this event */
1881                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.",
1882                     __FUNCTION__);
1883                 id = mRequestId; /* Use the saved mRequestId instead. */
1884             } else {
1885                 id = nla_get_u32(
1886                         tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1887                         );
1888                 /* If this is not for us, use the saved requestId */
1889                 if (id != mRequestId) {
1890                     ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1891                         __FUNCTION__, id, mRequestId);
1892                     id = mRequestId;
1893                 }
1894             }
1895 
1896             ret = gscan_parse_passpoint_network_result(tbVendor);
1897             /* If a parsing error occurred, exit and proceed for cleanup. */
1898             if (ret)
1899             {
1900                 ALOGE("%s: gscan_parse_passpoint_network_result"
1901                       "returned error: %d.\n", __FUNCTION__, ret);
1902                 break;
1903             }
1904             (*mHandler.on_passpoint_network_found)(id,
1905                                                    mPasspointNetId,
1906                                                    mPasspointNetworkFoundResult,
1907                                                    mPasspointAnqpLen,
1908                                                    mPasspointAnqp);
1909             if (mPasspointNetworkFoundResult)
1910             {
1911                 free(mPasspointNetworkFoundResult);
1912                 mPasspointNetworkFoundResult = NULL;
1913             }
1914             if (mPasspointAnqp)
1915             {
1916                 free(mPasspointAnqp);
1917                 mPasspointAnqp = NULL;
1918             }
1919             mPasspointNetId = -1;
1920             mPasspointAnqpLen = 0;
1921         }
1922         break;
1923         default:
1924             /* Error case should not happen print log */
1925             ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd);
1926     }
1927 
1928     /* A parsing error occurred, do the cleanup of gscan result lists. */
1929     if (ret) {
1930         switch(mSubcmd)
1931         {
1932             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
1933             {
1934                 free(result);
1935                 result = NULL;
1936             }
1937             break;
1938 
1939             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
1940             {
1941                 /* Reset flag and num counter. */
1942                 free(mHotlistApFoundResults);
1943                 mHotlistApFoundResults = NULL;
1944                 mHotlistApFoundMoreData = false;
1945                 mHotlistApFoundNumResults = 0;
1946             }
1947             break;
1948 
1949             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
1950             {
1951                 if (mSignificantChangeResults) {
1952                     for (i = 0; i < mSignificantChangeNumResults; i++)
1953                     {
1954                         if (mSignificantChangeResults[i]) {
1955                             free(mSignificantChangeResults[i]);
1956                             mSignificantChangeResults[i] = NULL;
1957                         }
1958                     }
1959                     free(mSignificantChangeResults);
1960                     mSignificantChangeResults = NULL;
1961                 }
1962                 mSignificantChangeNumResults = 0;
1963                 mSignificantChangeMoreData = false;
1964             }
1965             break;
1966 
1967             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
1968             break;
1969 
1970             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
1971             break;
1972 
1973             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST:
1974             {
1975                 /* Reset flag and num counter. */
1976                 free(mHotlistApLostResults);
1977                 mHotlistApLostResults = NULL;
1978                 mHotlistApLostMoreData = false;
1979                 mHotlistApLostNumResults = 0;
1980             }
1981             break;
1982 
1983             case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND:
1984             {
1985                 /* Reset flag and num counter. */
1986                 if (mPnoNetworkFoundResults) {
1987                     free(mPnoNetworkFoundResults);
1988                     mPnoNetworkFoundResults = NULL;
1989                 }
1990                 mPnoNetworkFoundMoreData = false;
1991                 mPnoNetworkFoundNumResults = 0;
1992             }
1993             break;
1994 
1995             case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND:
1996             {
1997                 if (mPasspointNetworkFoundResult)
1998                 {
1999                     free(mPasspointNetworkFoundResult);
2000                     mPasspointNetworkFoundResult = NULL;
2001                 }
2002                 if (mPasspointAnqp)
2003                 {
2004                     free(mPasspointAnqp);
2005                     mPasspointAnqp = NULL;
2006                 }
2007                 mPasspointNetId = -1;
2008                 mPasspointAnqpLen = 0;
2009             }
2010             break;
2011 
2012             default:
2013                 ALOGE("%s: Parsing err handler: wrong GScan subcmd "
2014                     "received %d", __FUNCTION__, mSubcmd);
2015         }
2016     }
2017     return NL_SKIP;
2018 }
2019