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 #include "gscan_event_handler.h"
18 #include "vendor_definitions.h"
19 
20 /* This function implements creation of Vendor command event handler. */
create()21 int GScanCommandEventHandler::create() {
22     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
23     if (ret < 0) {
24         return ret;
25     }
26 
27     /* Insert the oui in the msg */
28     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
29     if (ret < 0)
30         goto out;
31 
32     /* Insert the subcmd in the msg */
33     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
34     if (ret < 0)
35         goto out;
36 out:
37     return ret;
38 }
39 
get_request_id()40 int GScanCommandEventHandler::get_request_id()
41 {
42     return mRequestId;
43 }
44 
GScanCommandEventHandler(wifi_handle handle,int id,u32 vendor_id,u32 subcmd,GScanCallbackHandler handler)45 GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id,
46                                                 u32 vendor_id,
47                                                 u32 subcmd,
48                                                 GScanCallbackHandler handler)
49         : WifiVendorCommand(handle, id, vendor_id, subcmd)
50 {
51     int ret = 0;
52     ALOGD("GScanCommandEventHandler %p constructed", this);
53     mRequestId = id;
54     mHandler = handler;
55     mSubCommandId = subcmd;
56     mHotlistApFoundResults = NULL;
57     mHotlistApFoundNumResults = 0;
58     mHotlistApFoundMoreData = false;
59     mSignificantChangeResults = NULL;
60     mSignificantChangeNumResults = 0;
61     mSignificantChangeMoreData = false;
62 
63     switch(mSubCommandId)
64     {
65         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
66         {
67             /* Register handlers for northbound asychronous scan events. */
68             ALOGD("%s: wait for GSCAN_RESULTS_AVAILABLE, "
69                 "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __func__);
70             ret = registerVendorHandler(mVendor_id,
71                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE) ||
72                   registerVendorHandler(mVendor_id,
73                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) ||
74                   registerVendorHandler(mVendor_id,
75                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT);
76             if (ret < 0)
77                 ALOGD("%s: Error in registering handler for "
78                     "GSCAN_START. \n", __func__);
79         }
80         break;
81 
82         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
83         {
84             ret = registerVendorHandler(mVendor_id,
85                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE);
86             if (ret < 0)
87                 ALOGD("%s: Error in registering handler for "
88                     "GSCAN_SIGNIFICANT_CHANGE. \n", __func__);
89         }
90         break;
91 
92         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
93         {
94             ret = registerVendorHandler(mVendor_id,
95                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND);
96             if (ret < 0)
97                 ALOGD("%s: Error in registering handler for"
98                     " GSCAN_HOTLIST_AP_FOUND. \n", __func__);
99         }
100         break;
101     }
102 }
103 
~GScanCommandEventHandler()104 GScanCommandEventHandler::~GScanCommandEventHandler()
105 {
106     ALOGD("GScanCommandEventHandler %p destructor", this);
107     switch(mSubCommandId)
108     {
109         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START:
110         {
111             /* Unregister event handlers. */
112             ALOGD("%s: Unregister handlers for GSCAN_RESULTS_AVAILABLE, "
113             "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __func__);
114             unregisterVendorHandler(mVendor_id,
115                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE);
116             unregisterVendorHandler(mVendor_id,
117                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT);
118             unregisterVendorHandler(mVendor_id,
119                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT);
120         }
121         break;
122 
123         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE:
124         {
125             unregisterVendorHandler(mVendor_id,
126                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE);
127         }
128         break;
129 
130         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST:
131         {
132             unregisterVendorHandler(mVendor_id,
133                     QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND);
134         }
135         break;
136     }
137 }
138 
gscan_get_hotlist_ap_found_results(u32 num_results,wifi_scan_result * results,u32 starting_index,struct nlattr ** tb_vendor)139 static wifi_error gscan_get_hotlist_ap_found_results(u32 num_results,
140                                             wifi_scan_result *results,
141                                             u32 starting_index,
142                                             struct nlattr **tb_vendor)
143 {
144     u32 i = starting_index;
145     struct nlattr *scanResultsInfo;
146     int rem = 0;
147     u32 len = 0;
148     ALOGE("gscan_get_hotlist_ap_found_results: starting counter: %d", i);
149 
150     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
151             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
152             rem = nla_len(tb_vendor[
153             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST
154             ]);
155                 nla_ok(scanResultsInfo, rem);
156                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
157     {
158         struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
159         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
160         (struct nlattr *) nla_data(scanResultsInfo),
161                 nla_len(scanResultsInfo), NULL);
162 
163         if (!
164             tb2[
165                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
166                 ])
167         {
168             ALOGE("gscan_get_hotlist_ap_found_results: "
169                 "RESULTS_SCAN_RESULT_TIME_STAMP not found");
170             return WIFI_ERROR_INVALID_ARGS;
171         }
172         results[i].ts =
173             nla_get_u64(
174             tb2[
175                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
176                 ]);
177         if (!
178             tb2[
179                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
180                 ])
181         {
182             ALOGE("gscan_get_hotlist_ap_found_results: "
183                 "RESULTS_SCAN_RESULT_SSID not found");
184             return WIFI_ERROR_INVALID_ARGS;
185         }
186         len = nla_len(tb2[
187                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
188         len =
189             sizeof(results->ssid) <= len ? sizeof(results->ssid) : len;
190         memcpy((void *)&results[i].ssid,
191             nla_data(
192             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
193         if (!
194             tb2[
195                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
196                 ])
197         {
198             ALOGE("gscan_get_hotlist_ap_found_results: "
199                 "RESULTS_SCAN_RESULT_BSSID not found");
200             return WIFI_ERROR_INVALID_ARGS;
201         }
202         len = nla_len(
203             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
204         len =
205             sizeof(results->bssid) <= len ? sizeof(results->bssid) : len;
206         memcpy(&results[i].bssid,
207             nla_data(
208             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
209         if (!
210             tb2[
211                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
212                 ])
213         {
214             ALOGE("gscan_get_hotlist_ap_found_results: "
215                 "RESULTS_SCAN_RESULT_CHANNEL not found");
216             return WIFI_ERROR_INVALID_ARGS;
217         }
218         results[i].channel =
219             nla_get_u32(
220             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
221         if (!
222             tb2[
223                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
224                 ])
225         {
226             ALOGE("gscan_get_hotlist_ap_found_results: "
227                 "RESULTS_SCAN_RESULT_RSSI not found");
228             return WIFI_ERROR_INVALID_ARGS;
229         }
230         results[i].rssi =
231             nla_get_u32(
232             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]);
233         if (!
234             tb2[
235                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
236                 ])
237         {
238             ALOGE("gscan_get_hotlist_ap_found_results: "
239                 "RESULTS_SCAN_RESULT_RTT not found");
240             return WIFI_ERROR_INVALID_ARGS;
241         }
242         results[i].rtt =
243             nla_get_u32(
244             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
245         if (!
246             tb2[
247                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
248             ])
249         {
250             ALOGE("gscan_get_hotlist_ap_found_results: "
251                 "RESULTS_SCAN_RESULT_RTT_SD not found");
252             return WIFI_ERROR_INVALID_ARGS;
253         }
254         results[i].rtt_sd =
255             nla_get_u32(
256             tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
257 
258         ALOGE("gscan_get_hotlist_ap_found_results: ts  %lld ", results[i].ts);
259         ALOGE("gscan_get_hotlist_ap_found_results: SSID  %s ",
260             results[i].ssid) ;
261         ALOGE("gscan_get_hotlist_ap_found_results: "
262             "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
263             results[i].bssid[0], results[i].bssid[1], results[i].bssid[2],
264             results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]);
265         ALOGE("gscan_get_hotlist_ap_found_results: channel %d ",
266             results[i].channel);
267         ALOGE("gscan_get_hotlist_ap_found_results: rssi %d ", results[i].rssi);
268         ALOGE("gscan_get_hotlist_ap_found_results: rtt %lld ", results[i].rtt);
269         ALOGE("gscan_get_hotlist_ap_found_results: rtt_sd %lld ",
270             results[i].rtt_sd);
271         /* Increment loop index for next record */
272         i++;
273     }
274     return WIFI_SUCCESS;
275 }
276 
gscan_get_significant_change_results(u32 num_results,wifi_significant_change_result ** results,u32 starting_index,struct nlattr ** tb_vendor)277 static wifi_error gscan_get_significant_change_results(u32 num_results,
278                                     wifi_significant_change_result **results,
279                                     u32 starting_index,
280                                     struct nlattr **tb_vendor)
281 {
282     u32 i = starting_index;
283     int j;
284     int rem = 0;
285     u32 len = 0;
286     struct nlattr *scanResultsInfo;
287 
288     ALOGE("gscan_get_significant_change_results: starting counter: %d", i);
289 
290     for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[
291             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
292             rem = nla_len(tb_vendor[
293             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
294         nla_ok(scanResultsInfo, rem);
295         scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
296     {
297         struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
298         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
299             (struct nlattr *) nla_data(scanResultsInfo),
300                 nla_len(scanResultsInfo), NULL);
301         if (!
302             tb2[
303             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID
304             ])
305         {
306             ALOGE("gscan_get_significant_change_results: "
307                 "SIGNIFICANT_CHANGE_RESULT_BSSID not found");
308             return WIFI_ERROR_INVALID_ARGS;
309         }
310         len = nla_len(
311             tb2[
312             QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]
313             );
314         len =
315             sizeof(results[i]->bssid) <= len ? sizeof(results[i]->bssid) : len;
316         memcpy(&results[i]->bssid[0],
317             nla_data(
318             tb2[
319         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]),
320             len);
321         ALOGI("\nsignificant_change_result:%d, BSSID:"
322             "%02x:%02x:%02x:%02x:%02x:%02x \n", i, results[i]->bssid[0],
323             results[i]->bssid[1], results[i]->bssid[2], results[i]->bssid[3],
324             results[i]->bssid[4], results[i]->bssid[5]);
325 
326         if (!
327             tb2[
328         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL
329                 ])
330         {
331             ALOGE("gscan_get_significant_change_results: "
332                 "SIGNIFICANT_CHANGE_RESULT_CHANNEL not found");
333             return WIFI_ERROR_INVALID_ARGS;
334         }
335         results[i]->channel =
336             nla_get_u32(
337             tb2[
338         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL]);
339         ALOGI("significant_change_result:%d, channel:%d.\n",
340             i, results[i]->channel);
341 
342         if (!
343             tb2[
344         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
345             ])
346         {
347             ALOGE("gscan_get_significant_change_results: "
348                 "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found");
349             return WIFI_ERROR_INVALID_ARGS;
350         }
351         results[i]->num_rssi =
352             nla_get_u32(
353             tb2[
354         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI]);
355         ALOGI("gscan_get_significant_change_results: "
356             "significant_change_result:%d, num_rssi:%d.\n",
357             i, results[i]->num_rssi);
358 
359         if (!
360             tb2[
361         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST
362             ])
363         {
364             ALOGE("gscan_get_significant_change_results: "
365                 "SIGNIFICANT_CHANGE_RESULT_RSSI_LIST not found");
366             return WIFI_ERROR_INVALID_ARGS;
367         }
368         ALOGI("gscan_get_significant_change_results: before reading the RSSI "
369             "list: num_rssi:%d, size_of_rssi:%d, total size:%d, ",
370             results[i]->num_rssi,
371             sizeof(wifi_rssi), results[i]->num_rssi * sizeof(wifi_rssi));
372 
373         memcpy(&(results[i]->rssi[0]),
374             nla_data(
375             tb2[
376         QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST]
377             ), results[i]->num_rssi * sizeof(wifi_rssi));
378 
379         for (j = 0; j < results[i]->num_rssi; j++)
380             ALOGI("     significant_change_result: %d, rssi[%d]:%d, ",
381             i, j, results[i]->rssi[j]);
382 
383         /* Increment loop index to prase next record. */
384         i++;
385     }
386     return WIFI_SUCCESS;
387 }
388 
389 /* This function will be the main handler for incoming (from driver)  GSscan_SUBCMD.
390  *  Calls the appropriate callback handler after parsing the vendor data.
391  */
handleEvent(WifiEvent & event)392 int GScanCommandEventHandler::handleEvent(WifiEvent &event)
393 {
394     ALOGI("GScanCommandEventHandler::handleEvent: Got a GSCAN Event"
395         " message from the Driver.");
396     unsigned i=0;
397     int ret = WIFI_SUCCESS;
398     u32 status;
399     wifi_scan_result *result;
400     struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
401 
402     WifiVendorCommand::handleEvent(event);
403 
404     nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
405                         (struct nlattr *)mVendorData,
406                         mDataLen, NULL);
407 
408     switch(mSubcmd)
409     {
410         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
411         {
412             wifi_request_id reqId;
413             u32 len = 0;
414             u32 resultsBufSize = 0;
415             u32 lengthOfInfoElements = 0;
416 
417             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT "
418                 "received.");
419 
420             if (!tbVendor[
421                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
422             {
423                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
424                     __func__);
425                 ret = WIFI_ERROR_INVALID_ARGS;
426                 break;
427             }
428             reqId = nla_get_u32(
429                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
430                     );
431             /* If this is not for us, just ignore it. */
432             if (reqId != mRequestId) {
433                 ALOGE("%s: Event has Req. ID:%d <> Ours:%d, ignore it.",
434                     __func__, reqId, mRequestId);
435                 break;
436             }
437 
438             /* Parse and extract the results. */
439             if (!
440                 tbVendor[
441                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
442                 ])
443             {
444                 ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __func__);
445                 ret = WIFI_ERROR_INVALID_ARGS;
446                 break;
447             }
448             lengthOfInfoElements =
449                 nla_get_u32(
450                 tbVendor[
451                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
452             ALOGI("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d",
453                 __func__, lengthOfInfoElements);
454             resultsBufSize =
455                 lengthOfInfoElements + sizeof(wifi_scan_result);
456             result = (wifi_scan_result *) malloc (resultsBufSize);
457             if (!result) {
458                 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
459                     __func__);
460                 ret = WIFI_ERROR_OUT_OF_MEMORY;
461                 break;
462             }
463             memset(result, 0, resultsBufSize);
464 
465             result->ie_length = lengthOfInfoElements;
466 
467             /* Extract and fill out the wifi_scan_result struct. */
468             if (!
469             tbVendor[
470                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
471                 ])
472             {
473                 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
474                     __func__);
475                 ret = WIFI_ERROR_INVALID_ARGS;
476                 break;
477             }
478             result->ts =
479                 nla_get_u64(
480                 tbVendor[
481                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
482                     ]);
483 
484             if (!
485                 tbVendor[
486                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
487                     ])
488             {
489                 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __func__);
490                 ret = WIFI_ERROR_INVALID_ARGS;
491                 break;
492             }
493             len = nla_len(tbVendor[
494                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
495             len =
496                 sizeof(result->ssid) <= len ? sizeof(result->ssid) : len;
497             memcpy((void *)&result->ssid,
498                 nla_data(
499                 tbVendor[
500                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
501 
502             if (!
503                 tbVendor[
504                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
505                     ])
506             {
507                 ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __func__);
508                 ret = WIFI_ERROR_INVALID_ARGS;
509                 break;
510             }
511             len = nla_len(
512                 tbVendor[
513                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
514             len =
515                 sizeof(result->bssid) <= len ? sizeof(result->bssid) : len;
516             memcpy(&result->bssid,
517                 nla_data(
518                 tbVendor[
519                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
520 
521             if (!
522                 tbVendor[
523                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
524                     ])
525             {
526                 ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __func__);
527                 ret = WIFI_ERROR_INVALID_ARGS;
528                 break;
529             }
530             result->channel =
531                 nla_get_u32(
532                 tbVendor[
533                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
534 
535             if (!
536                 tbVendor[
537                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
538                     ])
539             {
540                 ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __func__);
541                 ret = WIFI_ERROR_INVALID_ARGS;
542                 break;
543             }
544             result->rssi =
545                 nla_get_u32(
546                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]
547                 );
548 
549             if (!
550                 tbVendor[
551                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
552                     ])
553             {
554                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __func__);
555                 ret = WIFI_ERROR_INVALID_ARGS;
556                 break;
557             }
558             result->rtt =
559                 nla_get_u32(
560                 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
561 
562             if (!
563                 tbVendor[
564                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
565                 ])
566             {
567                 ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __func__);
568                 ret = WIFI_ERROR_INVALID_ARGS;
569                 break;
570             }
571             result->rtt_sd =
572                 nla_get_u32(
573                 tbVendor[
574                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
575 
576             if (!
577                 tbVendor[
578                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
579             {
580                 ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
581                     __func__);
582                 ret = WIFI_ERROR_INVALID_ARGS;
583                 break;
584             }
585             result->beacon_period =
586                 nla_get_u16(
587                 tbVendor[
588                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
589 
590             if (!
591                 tbVendor[
592                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
593                     ])
594             {
595                 ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __func__);
596                 ret = WIFI_ERROR_INVALID_ARGS;
597                 break;
598             }
599             result->capability =
600                 nla_get_u16(
601                 tbVendor[
602                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
603 
604             if (!
605                 tbVendor[
606                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
607                 ])
608             {
609                 ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __func__);
610                 ret = WIFI_ERROR_INVALID_ARGS;
611                 break;
612             }
613             memcpy(&(result->ie_data[0]),
614                 nla_data(tbVendor[
615                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
616                 lengthOfInfoElements);
617 
618             ALOGE("handleEvent:FULL_SCAN_RESULTS: ts  %lld ", result->ts);
619             ALOGE("handleEvent:FULL_SCAN_RESULTS: SSID  %s ", result->ssid) ;
620             ALOGE("handleEvent:FULL_SCAN_RESULTS: "
621                 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
622                 result->bssid[0], result->bssid[1], result->bssid[2],
623                 result->bssid[3], result->bssid[4], result->bssid[5]);
624             ALOGE("handleEvent:FULL_SCAN_RESULTS: channel %d ",
625                 result->channel);
626             ALOGE("handleEvent:FULL_SCAN_RESULTS: rssi  %d ", result->rssi);
627             ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt  %lld ", result->rtt);
628             ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt_sd  %lld ",
629                 result->rtt_sd);
630             ALOGE("handleEvent:FULL_SCAN_RESULTS: beacon period  %d ",
631                 result->beacon_period);
632             ALOGE("handleEvent:FULL_SCAN_RESULTS: capability  %d ",
633                 result->capability);
634             ALOGE("handleEvent:FULL_SCAN_RESULTS: IE length  %d ",
635                 result->ie_length);
636 
637             ALOGE("%s: Invoking the callback. \n", __func__);
638             if (mHandler.on_full_scan_result) {
639                 (*mHandler.on_full_scan_result)(reqId, result);
640                 /* Reset flag and num counter. */
641                 free(result);
642                 result = NULL;
643             }
644         }
645         break;
646 
647         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
648         {
649             wifi_request_id id;
650             u32 numResults = 0;
651 
652             ALOGD("Event "
653                 "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE "
654                 "received.");
655 
656             if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
657                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID"
658                     "not found. Exit", __func__);
659                 ret = WIFI_ERROR_INVALID_ARGS;
660                 break;
661             }
662             id = nla_get_u32(
663                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
664                     );
665             /* If this is not for us, then ignore it. */
666             if (id != mRequestId) {
667                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
668                     __func__, id, mRequestId);
669                 break;
670             }
671             if (!tbVendor[
672                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
673                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
674                     __func__);
675                 ret = WIFI_ERROR_INVALID_ARGS;
676                 break;
677             }
678             numResults = nla_get_u32(tbVendor[
679                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
680             ALOGE("%s: number of results:%d", __func__, numResults);
681 
682             /* Invoke the callback func to report the number of results. */
683             ALOGE("%s: Calling on_scan_results_available handler",
684                 __func__);
685             if (!mHandler.on_scan_results_available) {
686                 break;
687             }
688             (*mHandler.on_scan_results_available)(id, numResults);
689         }
690         break;
691 
692         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
693         {
694             wifi_request_id id;
695             u32 resultsBufSize = 0;
696             u32 numResults = 0;
697             u32 startingIndex, sizeOfObtainedResults;
698 
699             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND "
700                 "received.");
701 
702             id = nla_get_u32(
703                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
704                     );
705             /* If this is not for us, just ignore it. */
706             if (id != mRequestId) {
707                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
708                     __func__, id, mRequestId);
709                 break;
710             }
711             if (!tbVendor[
712                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
713                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
714                     __func__);
715                 ret = WIFI_ERROR_INVALID_ARGS;
716                 break;
717             }
718             numResults = nla_get_u32(tbVendor[
719                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
720             ALOGE("%s: number of results:%d", __func__, numResults);
721 
722             /* Get the memory size of previous fragments, if any. */
723             sizeOfObtainedResults = mHotlistApFoundNumResults *
724                           sizeof(wifi_scan_result);
725 
726             mHotlistApFoundNumResults += numResults;
727             resultsBufSize += mHotlistApFoundNumResults *
728                                             sizeof(wifi_scan_result);
729 
730             /* Check if this chunck of scan results is a continuation of
731              * a previous one.
732              */
733             if (mHotlistApFoundMoreData) {
734                 mHotlistApFoundResults = (wifi_scan_result *)
735                             realloc (mHotlistApFoundResults, resultsBufSize);
736             } else {
737                 mHotlistApFoundResults = (wifi_scan_result *)
738                             malloc (resultsBufSize);
739             }
740 
741             if (!mHotlistApFoundResults) {
742                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
743                     __func__);
744                 ret = WIFI_ERROR_OUT_OF_MEMORY;
745                 break;
746             }
747             /* Initialize the newly allocated memory area with 0. */
748             memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0,
749                     resultsBufSize - sizeOfObtainedResults);
750 
751             ALOGE("%s: Num of AP FOUND results = %d. \n", __func__,
752                                             mHotlistApFoundNumResults);
753 
754             /* To support fragmentation from firmware, monitor the
755              * MORE_DTATA flag and cache results until MORE_DATA = 0.
756              * Only then we can pass on the results to framework through
757              * the callback function.
758              */
759             if (!tbVendor[
760                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
761                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
762                     " found", __func__);
763                 ret = WIFI_ERROR_INVALID_ARGS;
764                 break;
765             } else {
766                 mHotlistApFoundMoreData = nla_get_u8(
767                     tbVendor[
768                     QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
769                 ALOGE("%s: More data = %d. \n",
770                     __func__, mHotlistApFoundMoreData);
771             }
772 
773             ALOGE("%s: Extract hotlist_ap_found results.\n", __func__);
774             startingIndex = mHotlistApFoundNumResults - numResults;
775             ALOGE("%s: starting_index:%d",
776                 __func__, startingIndex);
777             ret = gscan_get_hotlist_ap_found_results(numResults,
778                                                 mHotlistApFoundResults,
779                                                 startingIndex,
780                                                 tbVendor);
781             /* If a parsing error occurred, exit and proceed for cleanup. */
782             if (ret)
783                 break;
784             /* Send the results if no more result data fragments are expected. */
785             if (!mHotlistApFoundMoreData) {
786                 (*mHandler.on_hotlist_ap_found)(id,
787                                                 mHotlistApFoundNumResults,
788                                                 mHotlistApFoundResults);
789                 /* Reset flag and num counter. */
790                 free(mHotlistApFoundResults);
791                 mHotlistApFoundResults = NULL;
792                 mHotlistApFoundMoreData = false;
793                 mHotlistApFoundNumResults = 0;
794             }
795         }
796         break;
797 
798         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
799         {
800             wifi_request_id reqId;
801             u32 numResults = 0, sizeOfObtainedResults;
802             u32 startingIndex, index = 0;
803             struct nlattr *scanResultsInfo;
804             int rem = 0;
805 
806             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE "
807                 "received.");
808 
809             if (!tbVendor[
810                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
811             {
812                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
813                     __func__);
814                 ret = WIFI_ERROR_INVALID_ARGS;
815                 break;
816             }
817             reqId = nla_get_u32(
818                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
819                     );
820             /* If this is not for us, just ignore it. */
821             if (reqId != mRequestId) {
822                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
823                     __func__, reqId, mRequestId);
824                 break;
825             }
826             if (!tbVendor[
827                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE])
828             {
829                 ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found."
830                     "Exit.", __func__);
831                 ret = WIFI_ERROR_INVALID_ARGS;
832                 break;
833             }
834             numResults = nla_get_u32(tbVendor[
835                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
836             /* Get the memory size of previous fragments, if any. */
837             sizeOfObtainedResults = sizeof(wifi_significant_change_result *) *
838                                 mSignificantChangeNumResults;
839 
840             index = mSignificantChangeNumResults;
841             mSignificantChangeNumResults += numResults;
842             /*
843              * Check if this chunck of wifi_significant_change results is a
844              * continuation of a previous one.
845              */
846             if (mSignificantChangeMoreData) {
847                 mSignificantChangeResults =
848                     (wifi_significant_change_result **)
849                         realloc (mSignificantChangeResults,
850                         sizeof(wifi_significant_change_result *) *
851                                 mSignificantChangeNumResults);
852             } else {
853                 mSignificantChangeResults =
854                     (wifi_significant_change_result **)
855                         malloc (sizeof(wifi_significant_change_result *) *
856                                 mSignificantChangeNumResults);
857             }
858 
859             if (!mSignificantChangeResults) {
860                 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
861                     __func__);
862                 ret = WIFI_ERROR_OUT_OF_MEMORY;
863                 break;
864             }
865             /* Initialize the newly allocated memory area with 0. */
866             memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0,
867                     sizeof(wifi_significant_change_result *) *
868                                 numResults);
869             ALOGD("%s: mSignificantChangeMoreData = %d",
870                     __func__, mSignificantChangeMoreData);
871 
872             for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[
873                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
874                 rem = nla_len(tbVendor[
875                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
876                 nla_ok(scanResultsInfo, rem);
877                 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
878             {
879                 u32 num_rssi = 0;
880                 u32 resultsBufSize = 0;
881                 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
882                 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
883                     (struct nlattr *) nla_data(scanResultsInfo),
884                     nla_len(scanResultsInfo), NULL);
885                 if (!tb2[
886                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
887                     ])
888                 {
889                     ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
890                         "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. "
891                         "Exit.", __func__);
892                     ret = WIFI_ERROR_INVALID_ARGS;
893                     break;
894                 }
895                 num_rssi = nla_get_u32(tb2[
896                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
897                         ]);
898                 resultsBufSize = sizeof(wifi_significant_change_result) +
899                             num_rssi * sizeof(wifi_rssi);
900                 mSignificantChangeResults[index] =
901                     (wifi_significant_change_result *) malloc (resultsBufSize);
902 
903                 if (!mSignificantChangeResults[index]) {
904                     ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
905                         __func__);
906                     ret = WIFI_ERROR_OUT_OF_MEMORY;
907                     break;
908                 }
909                 /* Initialize the newly allocated memory area with 0. */
910                 memset((u8 *)mSignificantChangeResults[index],
911                         0, resultsBufSize);
912 
913                 ALOGE("%s: For Significant Change results[%d], num_rssi:%d\n",
914                     __func__, index, num_rssi);
915                 index++;
916             }
917 
918             ALOGE("%s: Extract significant change results.\n", __func__);
919             startingIndex =
920                 mSignificantChangeNumResults - numResults;
921             ret = gscan_get_significant_change_results(numResults,
922                                                 mSignificantChangeResults,
923                                                 startingIndex,
924                                                 tbVendor);
925             /* If a parsing error occurred, exit and proceed for cleanup. */
926             if (ret)
927                 break;
928             /* To support fragmentation from firmware, monitor the
929              * MORE_DTATA flag and cache results until MORE_DATA = 0.
930              * Only then we can pass on the results to framework through
931              * the callback function.
932              */
933             if (!tbVendor[
934                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
935                 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
936                     " found. Stop parsing and exit.", __func__);
937                 break;
938             }
939             mSignificantChangeMoreData = nla_get_u8(
940                 tbVendor[
941                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
942             ALOGE("%s: More data = %d. \n",
943                 __func__, mSignificantChangeMoreData);
944 
945             /* Send the results if no more result fragments are expected */
946             if (!mSignificantChangeMoreData) {
947                 ALOGE("%s: Invoking the callback. \n", __func__);
948                 (*mHandler.on_significant_change)(reqId,
949                                               mSignificantChangeNumResults,
950                                               mSignificantChangeResults);
951                 /* Reset flag and num counter. */
952                 for (index = 0; index  < mSignificantChangeNumResults; index++)
953                 {
954                     free(mSignificantChangeResults[index]);
955                     mSignificantChangeResults[index] = NULL;
956                 }
957                 free(mSignificantChangeResults);
958                 mSignificantChangeResults = NULL;
959                 mSignificantChangeNumResults = 0;
960                 mSignificantChangeMoreData = false;
961             }
962         }
963         break;
964 
965         case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
966         {
967             wifi_scan_event scanEvent;
968             u32 scanEventStatus = 0;
969             wifi_request_id reqId;
970 
971             ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT "
972                 "received.");
973 
974             if (!tbVendor[
975                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
976             {
977                 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
978                     __func__);
979                 ret = WIFI_ERROR_INVALID_ARGS;
980                 break;
981             }
982             reqId = nla_get_u32(
983                     tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
984                     );
985             /* If this is not for us, just ignore it. */
986             if (reqId != mRequestId) {
987                 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
988                     __func__, reqId, mRequestId);
989                 break;
990             }
991 
992             if (!tbVendor[
993                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) {
994                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not"
995                     " found. Stop parsing and exit.", __func__);
996                 break;
997             }
998             scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[
999                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]);
1000 
1001             if (!tbVendor[
1002                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]) {
1003                 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_STATUS not"
1004                     " found. Stop parsing and exit.", __func__);
1005                 break;
1006             }
1007             scanEventStatus = nla_get_u32(tbVendor[
1008                 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]);
1009 
1010             ALOGE("%s: Scan event type: %d, status = %d. \n", __func__,
1011                                     scanEvent, scanEventStatus);
1012             /* Send the results if no more result fragments are expected. */
1013             (*mHandler.on_scan_event)(scanEvent, scanEventStatus);
1014         }
1015         break;
1016 
1017         default:
1018             /* Error case should not happen print log */
1019             ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd);
1020     }
1021 
1022     /* A parsing error occurred, do the cleanup of gscan result lists. */
1023     if (ret) {
1024         switch(mSubcmd)
1025         {
1026             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
1027             {
1028                 free(result);
1029                 result = NULL;
1030             }
1031             break;
1032 
1033             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
1034             {
1035                 /* Reset flag and num counter. */
1036                 free(mHotlistApFoundResults);
1037                 mHotlistApFoundResults = NULL;
1038                 mHotlistApFoundMoreData = false;
1039                 mHotlistApFoundNumResults = 0;
1040             }
1041             break;
1042 
1043             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
1044             {
1045                 for (i = 0; i < mSignificantChangeNumResults; i++)
1046                 {
1047                     if (mSignificantChangeResults[i]) {
1048                         free(mSignificantChangeResults[i]);
1049                         mSignificantChangeResults[i] = NULL;
1050                     }
1051                 }
1052                 free(mSignificantChangeResults);
1053                 mSignificantChangeResults = NULL;
1054                 mSignificantChangeNumResults = 0;
1055                 mSignificantChangeMoreData = false;
1056             }
1057             break;
1058 
1059             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
1060             break;
1061 
1062             case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
1063             break;
1064 
1065             default:
1066                 ALOGE("%s: Parsing err handler: wrong GScan subcmd "
1067                     "received %d", __func__, mSubcmd);
1068         }
1069     }
1070     return NL_SKIP;
1071 }
1072