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