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