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