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