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 u32 status;
1045 wifi_scan_result *result = NULL;
1046 struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
1047
1048 if (mEventHandlingEnabled == false)
1049 {
1050 ALOGV("%s:Discarding event: %d",
1051 __FUNCTION__, mSubcmd);
1052 return NL_SKIP;
1053 }
1054
1055 WifiVendorCommand::handleEvent(event);
1056
1057 nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
1058 (struct nlattr *)mVendorData,
1059 mDataLen, NULL);
1060
1061 switch(mSubcmd)
1062 {
1063 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
1064 {
1065 wifi_request_id reqId;
1066 u32 len = 0;
1067 u32 resultsBufSize = 0;
1068 u32 lengthOfInfoElements = 0;
1069 u32 buckets_scanned = 0;
1070
1071 ALOGV("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT "
1072 "received.");
1073
1074 if (!tbVendor[
1075 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1076 {
1077 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1078 __FUNCTION__);
1079 ret = WIFI_ERROR_INVALID_ARGS;
1080 break;
1081 }
1082 reqId = nla_get_u32(
1083 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1084 );
1085 /* If event has a different request_id, ignore that and use the
1086 * request_id value which we're maintaining.
1087 */
1088 if (reqId != mRequestId) {
1089 #ifdef QC_HAL_DEBUG
1090 ALOGE("%s: Event has Req. ID:%d <> Ours:%d, continue...",
1091 __FUNCTION__, reqId, mRequestId);
1092 #endif
1093 reqId = mRequestId;
1094 }
1095
1096 /* Parse and extract the results. */
1097 if (!
1098 tbVendor[
1099 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
1100 ])
1101 {
1102 ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __FUNCTION__);
1103 ret = WIFI_ERROR_INVALID_ARGS;
1104 break;
1105 }
1106 lengthOfInfoElements =
1107 nla_get_u32(
1108 tbVendor[
1109 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]);
1110
1111 ALOGV("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d",
1112 __FUNCTION__, lengthOfInfoElements);
1113
1114 resultsBufSize =
1115 lengthOfInfoElements + sizeof(wifi_scan_result);
1116 result = (wifi_scan_result *) malloc (resultsBufSize);
1117 if (!result) {
1118 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n",
1119 __FUNCTION__);
1120 ret = WIFI_ERROR_OUT_OF_MEMORY;
1121 break;
1122 }
1123 memset(result, 0, resultsBufSize);
1124
1125 result->ie_length = lengthOfInfoElements;
1126
1127 /* Extract and fill out the wifi_scan_result struct. */
1128 if (!
1129 tbVendor[
1130 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
1131 ])
1132 {
1133 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found",
1134 __FUNCTION__);
1135 ret = WIFI_ERROR_INVALID_ARGS;
1136 break;
1137 }
1138 result->ts =
1139 nla_get_u64(
1140 tbVendor[
1141 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
1142 ]);
1143
1144 if (!
1145 tbVendor[
1146 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID
1147 ])
1148 {
1149 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __FUNCTION__);
1150 ret = WIFI_ERROR_INVALID_ARGS;
1151 break;
1152 }
1153 len = nla_len(tbVendor[
1154 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]);
1155 len =
1156 sizeof(result->ssid) <= len ? sizeof(result->ssid) : len;
1157 memcpy((void *)&result->ssid,
1158 nla_data(
1159 tbVendor[
1160 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len);
1161
1162 if (!
1163 tbVendor[
1164 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID
1165 ])
1166 {
1167 ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __FUNCTION__);
1168 ret = WIFI_ERROR_INVALID_ARGS;
1169 break;
1170 }
1171 len = nla_len(
1172 tbVendor[
1173 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]);
1174 len =
1175 sizeof(result->bssid) <= len ? sizeof(result->bssid) : len;
1176 memcpy(&result->bssid,
1177 nla_data(
1178 tbVendor[
1179 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len);
1180
1181 if (!
1182 tbVendor[
1183 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL
1184 ])
1185 {
1186 ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __FUNCTION__);
1187 ret = WIFI_ERROR_INVALID_ARGS;
1188 break;
1189 }
1190 result->channel =
1191 nla_get_u32(
1192 tbVendor[
1193 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]);
1194
1195 if (!
1196 tbVendor[
1197 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI
1198 ])
1199 {
1200 ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __FUNCTION__);
1201 ret = WIFI_ERROR_INVALID_ARGS;
1202 break;
1203 }
1204 result->rssi =
1205 get_s32(
1206 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]
1207 );
1208
1209 if (!
1210 tbVendor[
1211 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT
1212 ])
1213 {
1214 ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __FUNCTION__);
1215 ret = WIFI_ERROR_INVALID_ARGS;
1216 break;
1217 }
1218 result->rtt =
1219 nla_get_u32(
1220 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]);
1221
1222 if (!
1223 tbVendor[
1224 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD
1225 ])
1226 {
1227 ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __FUNCTION__);
1228 ret = WIFI_ERROR_INVALID_ARGS;
1229 break;
1230 }
1231 result->rtt_sd =
1232 nla_get_u32(
1233 tbVendor[
1234 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]);
1235
1236 if (!
1237 tbVendor[
1238 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD])
1239 {
1240 ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found",
1241 __FUNCTION__);
1242 ret = WIFI_ERROR_INVALID_ARGS;
1243 break;
1244 }
1245 result->beacon_period =
1246 nla_get_u16(
1247 tbVendor[
1248 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]);
1249
1250 if (!
1251 tbVendor[
1252 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY
1253 ])
1254 {
1255 ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__);
1256 ret = WIFI_ERROR_INVALID_ARGS;
1257 break;
1258 }
1259 result->capability =
1260 nla_get_u16(
1261 tbVendor[
1262 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]);
1263
1264 if (!
1265 tbVendor[
1266 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA
1267 ])
1268 {
1269 ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __FUNCTION__);
1270 ret = WIFI_ERROR_INVALID_ARGS;
1271 break;
1272 }
1273 memcpy(&(result->ie_data[0]),
1274 nla_data(tbVendor[
1275 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]),
1276 lengthOfInfoElements);
1277 if (!
1278 tbVendor[
1279 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED
1280 ])
1281 {
1282 ALOGD("%s: RESULTS_BUCKETS_SCANNED not found", __FUNCTION__);
1283 } else {
1284 buckets_scanned = get_u32(tbVendor[
1285 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]);
1286 }
1287 #ifdef QC_HAL_DEBUG
1288 ALOGD("handleEvent:FULL_SCAN_RESULTS: ts %" PRId64, result->ts);
1289 ALOGD("handleEvent:FULL_SCAN_RESULTS: SSID %s ", result->ssid) ;
1290 ALOGD("handleEvent:FULL_SCAN_RESULTS: "
1291 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
1292 result->bssid[0], result->bssid[1], result->bssid[2],
1293 result->bssid[3], result->bssid[4], result->bssid[5]);
1294 ALOGD("handleEvent:FULL_SCAN_RESULTS: channel %d ",
1295 result->channel);
1296 ALOGD("handleEvent:FULL_SCAN_RESULTS: rssi %d ", result->rssi);
1297 ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt %" PRId64, result->rtt);
1298 ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt_sd %" PRId64,
1299 result->rtt_sd);
1300 ALOGD("handleEvent:FULL_SCAN_RESULTS: beacon period %d ",
1301 result->beacon_period);
1302 ALOGD("handleEvent:FULL_SCAN_RESULTS: capability %d ",
1303 result->capability);
1304 ALOGD("handleEvent:FULL_SCAN_RESULTS: IE length %d ",
1305 result->ie_length);
1306
1307 ALOGD("%s: Invoking the callback. \n", __FUNCTION__);
1308 #endif
1309 if (mHandler.on_full_scan_result) {
1310 (*mHandler.on_full_scan_result)(reqId, result, buckets_scanned);
1311 /* Reset flag and num counter. */
1312 free(result);
1313 result = NULL;
1314 }
1315 }
1316 break;
1317
1318 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
1319 {
1320 wifi_request_id id;
1321
1322 #ifdef QC_HAL_DEBUG
1323 ALOGV("Event "
1324 "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE "
1325 "received.");
1326 #endif
1327
1328 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) {
1329 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID"
1330 "not found. Exit", __FUNCTION__);
1331 ret = WIFI_ERROR_INVALID_ARGS;
1332 break;
1333 }
1334 id = nla_get_u32(
1335 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1336 );
1337 /* If this is not for us, then ignore it. */
1338 if (id != mRequestId) {
1339 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1340 __FUNCTION__, id, mRequestId);
1341 break;
1342 }
1343
1344 /* Invoke the callback func to report the number of results. */
1345 ALOGV("%s: Calling on_scan_event handler", __FUNCTION__);
1346 (*mHandler.on_scan_event)(id, WIFI_SCAN_THRESHOLD_NUM_SCANS);
1347 }
1348 break;
1349
1350 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
1351 {
1352 wifi_request_id id;
1353 u32 resultsBufSize = 0;
1354 u32 numResults = 0;
1355 u32 startingIndex, sizeOfObtainedResults;
1356
1357 id = nla_get_u32(
1358 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1359 );
1360 /* If this is not for us, just ignore it. */
1361 if (id != mRequestId) {
1362 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1363 __FUNCTION__, id, mRequestId);
1364 break;
1365 }
1366 if (!tbVendor[
1367 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1368 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1369 __FUNCTION__);
1370 ret = WIFI_ERROR_INVALID_ARGS;
1371 break;
1372 }
1373 numResults = nla_get_u32(tbVendor[
1374 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1375 ALOGV("%s: number of results:%d", __FUNCTION__, numResults);
1376
1377 /* Get the memory size of previous fragments, if any. */
1378 sizeOfObtainedResults = mHotlistApFoundNumResults *
1379 sizeof(wifi_scan_result);
1380
1381 mHotlistApFoundNumResults += numResults;
1382 resultsBufSize += mHotlistApFoundNumResults *
1383 sizeof(wifi_scan_result);
1384
1385 /* Check if this chunck of scan results is a continuation of
1386 * a previous one.
1387 */
1388 if (mHotlistApFoundMoreData) {
1389 mHotlistApFoundResults = (wifi_scan_result *)
1390 realloc (mHotlistApFoundResults, resultsBufSize);
1391 } else {
1392 mHotlistApFoundResults = (wifi_scan_result *)
1393 malloc (resultsBufSize);
1394 }
1395
1396 if (!mHotlistApFoundResults) {
1397 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1398 __FUNCTION__);
1399 ret = WIFI_ERROR_OUT_OF_MEMORY;
1400 break;
1401 }
1402 /* Initialize the newly allocated memory area with 0. */
1403 memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0,
1404 resultsBufSize - sizeOfObtainedResults);
1405
1406 ALOGV("%s: Num of AP FOUND results = %d. \n", __FUNCTION__,
1407 mHotlistApFoundNumResults);
1408
1409 /* To support fragmentation from firmware, monitor the
1410 * MORE_DATA flag and cache results until MORE_DATA = 0.
1411 * Only then we can pass on the results to framework through
1412 * the callback function.
1413 */
1414 if (!tbVendor[
1415 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1416 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1417 " found", __FUNCTION__);
1418 ret = WIFI_ERROR_INVALID_ARGS;
1419 break;
1420 } else {
1421 mHotlistApFoundMoreData = nla_get_u8(
1422 tbVendor[
1423 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1424 ALOGE("%s: More data = %d. \n",
1425 __FUNCTION__, mHotlistApFoundMoreData);
1426 }
1427
1428 ALOGV("%s: Extract hotlist_ap_found results.\n", __FUNCTION__);
1429 startingIndex = mHotlistApFoundNumResults - numResults;
1430 ALOGV("%s: starting_index:%d",
1431 __FUNCTION__, startingIndex);
1432 ret = gscan_parse_hotlist_ap_results(numResults,
1433 mHotlistApFoundResults,
1434 startingIndex,
1435 tbVendor);
1436 /* If a parsing error occurred, exit and proceed for cleanup. */
1437 if (ret)
1438 break;
1439 /* Send the results if no more result data fragments are expected */
1440 if (!mHotlistApFoundMoreData) {
1441 (*mHandler.on_hotlist_ap_found)(id,
1442 mHotlistApFoundNumResults,
1443 mHotlistApFoundResults);
1444 /* Reset flag and num counter. */
1445 free(mHotlistApFoundResults);
1446 mHotlistApFoundResults = NULL;
1447 mHotlistApFoundMoreData = false;
1448 mHotlistApFoundNumResults = 0;
1449 }
1450 }
1451 break;
1452
1453 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST:
1454 {
1455 wifi_request_id id;
1456 u32 resultsBufSize = 0;
1457 u32 numResults = 0;
1458 u32 startingIndex, sizeOfObtainedResults;
1459
1460 id = nla_get_u32(
1461 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1462 );
1463 /* If this is not for us, just ignore it. */
1464 if (id != mRequestId) {
1465 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1466 __FUNCTION__, id, mRequestId);
1467 break;
1468 }
1469 if (!tbVendor[
1470 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1471 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1472 __FUNCTION__);
1473 ret = WIFI_ERROR_INVALID_ARGS;
1474 break;
1475 }
1476 numResults = nla_get_u32(tbVendor[
1477 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1478 ALOGV("%s: number of results:%d", __FUNCTION__, numResults);
1479
1480 /* Get the memory size of previous fragments, if any. */
1481 sizeOfObtainedResults = mHotlistApLostNumResults *
1482 sizeof(wifi_scan_result);
1483
1484 mHotlistApLostNumResults += numResults;
1485 resultsBufSize += mHotlistApLostNumResults *
1486 sizeof(wifi_scan_result);
1487
1488 /* Check if this chunck of scan results is a continuation of
1489 * a previous one.
1490 */
1491 if (mHotlistApLostMoreData) {
1492 mHotlistApLostResults = (wifi_scan_result *)
1493 realloc (mHotlistApLostResults, resultsBufSize);
1494 } else {
1495 mHotlistApLostResults = (wifi_scan_result *)
1496 malloc (resultsBufSize);
1497 }
1498
1499 if (!mHotlistApLostResults) {
1500 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1501 __FUNCTION__);
1502 ret = WIFI_ERROR_OUT_OF_MEMORY;
1503 break;
1504 }
1505 /* Initialize the newly allocated memory area with 0. */
1506 memset((u8 *)mHotlistApLostResults + sizeOfObtainedResults, 0,
1507 resultsBufSize - sizeOfObtainedResults);
1508
1509 ALOGV("%s: Num of AP Lost results = %d. \n", __FUNCTION__,
1510 mHotlistApLostNumResults);
1511
1512 /* To support fragmentation from firmware, monitor the
1513 * MORE_DATA flag and cache results until MORE_DATA = 0.
1514 * Only then we can pass on the results to framework through
1515 * the callback function.
1516 */
1517 if (!tbVendor[
1518 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1519 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1520 " found", __FUNCTION__);
1521 ret = WIFI_ERROR_INVALID_ARGS;
1522 break;
1523 } else {
1524 mHotlistApLostMoreData = nla_get_u8(
1525 tbVendor[
1526 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1527 ALOGV("%s: More data = %d. \n",
1528 __FUNCTION__, mHotlistApLostMoreData);
1529 }
1530
1531 ALOGV("%s: Extract hotlist_ap_Lost results.\n", __FUNCTION__);
1532 startingIndex = mHotlistApLostNumResults - numResults;
1533 ALOGV("%s: starting_index:%d",
1534 __FUNCTION__, startingIndex);
1535 ret = gscan_parse_hotlist_ap_results(numResults,
1536 mHotlistApLostResults,
1537 startingIndex,
1538 tbVendor);
1539 /* If a parsing error occurred, exit and proceed for cleanup. */
1540 if (ret)
1541 break;
1542 /* Send the results if no more result data fragments are expected */
1543 if (!mHotlistApLostMoreData) {
1544 (*mHandler.on_hotlist_ap_lost)(id,
1545 mHotlistApLostNumResults,
1546 mHotlistApLostResults);
1547 /* Reset flag and num counter. */
1548 free(mHotlistApLostResults);
1549 mHotlistApLostResults = NULL;
1550 mHotlistApLostMoreData = false;
1551 mHotlistApLostNumResults = 0;
1552 }
1553 }
1554 break;
1555
1556 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
1557 {
1558 wifi_request_id reqId;
1559 u32 numResults = 0, sizeOfObtainedResults;
1560 u32 startingIndex, index = 0;
1561 struct nlattr *scanResultsInfo;
1562 int rem = 0;
1563
1564 if (!tbVendor[
1565 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1566 {
1567 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1568 __FUNCTION__);
1569 ret = WIFI_ERROR_INVALID_ARGS;
1570 break;
1571 }
1572 reqId = nla_get_u32(
1573 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1574 );
1575 /* If this is not for us, just ignore it. */
1576 if (reqId != mRequestId) {
1577 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1578 __FUNCTION__, reqId, mRequestId);
1579 break;
1580 }
1581 if (!tbVendor[
1582 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE])
1583 {
1584 ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found."
1585 "Exit.", __FUNCTION__);
1586 ret = WIFI_ERROR_INVALID_ARGS;
1587 break;
1588 }
1589 numResults = nla_get_u32(tbVendor[
1590 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1591 /* Get the memory size of previous fragments, if any. */
1592 sizeOfObtainedResults = sizeof(wifi_significant_change_result *) *
1593 mSignificantChangeNumResults;
1594
1595 index = mSignificantChangeNumResults;
1596 mSignificantChangeNumResults += numResults;
1597 /*
1598 * Check if this chunck of wifi_significant_change results is a
1599 * continuation of a previous one.
1600 */
1601 if (mSignificantChangeMoreData) {
1602 mSignificantChangeResults =
1603 (wifi_significant_change_result **)
1604 realloc (mSignificantChangeResults,
1605 sizeof(wifi_significant_change_result *) *
1606 mSignificantChangeNumResults);
1607 } else {
1608 mSignificantChangeResults =
1609 (wifi_significant_change_result **)
1610 malloc (sizeof(wifi_significant_change_result *) *
1611 mSignificantChangeNumResults);
1612 }
1613
1614 if (!mSignificantChangeResults) {
1615 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1616 __FUNCTION__);
1617 ret = WIFI_ERROR_OUT_OF_MEMORY;
1618 break;
1619 }
1620 /* Initialize the newly allocated memory area with 0. */
1621 memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0,
1622 sizeof(wifi_significant_change_result *) *
1623 numResults);
1624 ALOGV("%s: mSignificantChangeMoreData = %d",
1625 __FUNCTION__, mSignificantChangeMoreData);
1626
1627 for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[
1628 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
1629 rem = nla_len(tbVendor[
1630 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
1631 nla_ok(scanResultsInfo, rem);
1632 scanResultsInfo = nla_next(scanResultsInfo, &(rem)))
1633 {
1634 u32 num_rssi = 0;
1635 u32 resultsBufSize = 0;
1636 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
1637 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
1638 (struct nlattr *) nla_data(scanResultsInfo),
1639 nla_len(scanResultsInfo), NULL);
1640 if (!tb2[
1641 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
1642 ])
1643 {
1644 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_"
1645 "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. "
1646 "Exit.", __FUNCTION__);
1647 ret = WIFI_ERROR_INVALID_ARGS;
1648 break;
1649 }
1650 num_rssi = nla_get_u32(tb2[
1651 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI
1652 ]);
1653 resultsBufSize = sizeof(wifi_significant_change_result) +
1654 num_rssi * sizeof(wifi_rssi);
1655 mSignificantChangeResults[index] =
1656 (wifi_significant_change_result *) malloc (resultsBufSize);
1657
1658 if (!mSignificantChangeResults[index]) {
1659 ALOGE("%s: Failed to alloc memory for results array Exit",
1660 __FUNCTION__);
1661 ret = WIFI_ERROR_OUT_OF_MEMORY;
1662 break;
1663 }
1664 /* Initialize the newly allocated memory area with 0. */
1665 memset((u8 *)mSignificantChangeResults[index],
1666 0, resultsBufSize);
1667
1668 ALOGV("%s: For Significant Change results[%d], num_rssi:%d\n",
1669 __FUNCTION__, index, num_rssi);
1670 index++;
1671 }
1672
1673 ALOGV("%s: Extract significant change results.\n", __FUNCTION__);
1674 startingIndex =
1675 mSignificantChangeNumResults - numResults;
1676 ret = gscan_get_significant_change_results(numResults,
1677 mSignificantChangeResults,
1678 startingIndex,
1679 tbVendor);
1680 /* If a parsing error occurred, exit and proceed for cleanup. */
1681 if (ret)
1682 break;
1683 /* To support fragmentation from firmware, monitor the
1684 * MORE_DATA flag and cache results until MORE_DATA = 0.
1685 * Only then we can pass on the results to framework through
1686 * the callback function.
1687 */
1688 if (!tbVendor[
1689 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1690 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1691 " found. Stop parsing and exit.", __FUNCTION__);
1692 break;
1693 }
1694 mSignificantChangeMoreData = nla_get_u8(
1695 tbVendor[
1696 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1697 ALOGV("%s: More data = %d. \n",
1698 __FUNCTION__, mSignificantChangeMoreData);
1699
1700 /* Send the results if no more result fragments are expected */
1701 if (!mSignificantChangeMoreData) {
1702 ALOGV("%s: Invoking the callback. \n", __FUNCTION__);
1703 (*mHandler.on_significant_change)(reqId,
1704 mSignificantChangeNumResults,
1705 mSignificantChangeResults);
1706 if (mSignificantChangeResults) {
1707 /* Reset flag and num counter. */
1708 for (index = 0; index < mSignificantChangeNumResults;
1709 index++)
1710 {
1711 free(mSignificantChangeResults[index]);
1712 mSignificantChangeResults[index] = NULL;
1713 }
1714 free(mSignificantChangeResults);
1715 mSignificantChangeResults = NULL;
1716 }
1717 mSignificantChangeNumResults = 0;
1718 mSignificantChangeMoreData = false;
1719 }
1720 }
1721 break;
1722
1723 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
1724 {
1725 wifi_scan_event scanEvent;
1726 u32 scanEventStatus = 0;
1727 wifi_request_id reqId;
1728
1729 if (!tbVendor[
1730 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1731 {
1732 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.",
1733 __FUNCTION__);
1734 ret = WIFI_ERROR_INVALID_ARGS;
1735 break;
1736 }
1737 reqId = nla_get_u32(
1738 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1739 );
1740 /* If this is not for us, just ignore it. */
1741 if (reqId != mRequestId) {
1742 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1743 __FUNCTION__, reqId, mRequestId);
1744 break;
1745 }
1746
1747 if (!tbVendor[
1748 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) {
1749 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not"
1750 " found. Stop parsing and exit.", __FUNCTION__);
1751 break;
1752 }
1753 scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[
1754 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]);
1755
1756 ALOGV("%s: Scan event type: %d\n", __FUNCTION__, scanEvent);
1757 /* Send the results if no more result fragments are expected. */
1758 (*mHandler.on_scan_event)(reqId, scanEvent);
1759 }
1760 break;
1761
1762 case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND:
1763 {
1764 wifi_request_id id;
1765 u32 resultsBufSize = 0;
1766 u32 numResults = 0;
1767 u32 startingIndex, sizeOfObtainedResults;
1768
1769 if (!tbVendor[
1770 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1771 {
1772 /* RequestId is not provided by FW/Driver for this event */
1773 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.",
1774 __FUNCTION__);
1775 id = mRequestId; /* Use the saved mRequestId instead. */
1776 } else {
1777 id = nla_get_u32(
1778 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1779 );
1780 /* If this is not for us, use the saved requestId */
1781 if (id != mRequestId) {
1782 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1783 __FUNCTION__, id, mRequestId);
1784 id = mRequestId;
1785 }
1786 }
1787
1788 if (!tbVendor[
1789 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) {
1790 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found",
1791 __FUNCTION__);
1792 ret = WIFI_ERROR_INVALID_ARGS;
1793 break;
1794 }
1795 numResults = nla_get_u32(tbVendor[
1796 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
1797 ALOGV("%s: number of results:%d", __FUNCTION__, numResults);
1798
1799 /* Get the memory size of previous fragments, if any. */
1800 sizeOfObtainedResults = mPnoNetworkFoundNumResults *
1801 sizeof(wifi_scan_result);
1802
1803 mPnoNetworkFoundNumResults += numResults;
1804 resultsBufSize += mPnoNetworkFoundNumResults *
1805 sizeof(wifi_scan_result);
1806
1807 /* Check if this chunck of scan results is a continuation of
1808 * a previous one.
1809 */
1810 if (mPnoNetworkFoundMoreData) {
1811 mPnoNetworkFoundResults = (wifi_scan_result *)
1812 realloc (mPnoNetworkFoundResults, resultsBufSize);
1813 } else {
1814 mPnoNetworkFoundResults = (wifi_scan_result *)
1815 malloc (resultsBufSize);
1816 }
1817
1818 if (!mPnoNetworkFoundResults) {
1819 ALOGE("%s: Failed to alloc memory for results array. Exit.\n",
1820 __FUNCTION__);
1821 ret = WIFI_ERROR_OUT_OF_MEMORY;
1822 break;
1823 }
1824 /* Initialize the newly allocated memory area with 0. */
1825 memset((u8 *)mPnoNetworkFoundResults + sizeOfObtainedResults, 0,
1826 resultsBufSize - sizeOfObtainedResults);
1827
1828 ALOGV("%s: Num of AP FOUND results = %d. \n", __FUNCTION__,
1829 mPnoNetworkFoundNumResults);
1830
1831 /* To support fragmentation from firmware, monitor the
1832 * MORE_DATA flag and cache results until MORE_DATA = 0.
1833 * Only then we can pass on the results to framework through
1834 * the callback function.
1835 */
1836 if (!tbVendor[
1837 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) {
1838 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not"
1839 " found", __FUNCTION__);
1840 ret = WIFI_ERROR_INVALID_ARGS;
1841 break;
1842 } else {
1843 mPnoNetworkFoundMoreData = nla_get_u8(
1844 tbVendor[
1845 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]);
1846 ALOGV("%s: More data = %d. \n",
1847 __FUNCTION__, mPnoNetworkFoundMoreData);
1848 }
1849
1850 ALOGV("%s: Extract PNO_NETWORK_FOUND results.\n", __FUNCTION__);
1851 startingIndex = mPnoNetworkFoundNumResults - numResults;
1852 ALOGV("%s: starting_index:%d",
1853 __FUNCTION__, startingIndex);
1854 ret = gscan_parse_pno_network_results(numResults,
1855 mPnoNetworkFoundResults,
1856 startingIndex,
1857 tbVendor);
1858 /* If a parsing error occurred, exit and proceed for cleanup. */
1859 if (ret)
1860 break;
1861 /* Send the results if no more result data fragments are expected */
1862 if (!mPnoNetworkFoundMoreData) {
1863 (*mHandler.on_pno_network_found)(id,
1864 mPnoNetworkFoundNumResults,
1865 mPnoNetworkFoundResults);
1866 /* Reset flag and num counter. */
1867 if (mPnoNetworkFoundResults) {
1868 free(mPnoNetworkFoundResults);
1869 mPnoNetworkFoundResults = NULL;
1870 }
1871 mPnoNetworkFoundMoreData = false;
1872 mPnoNetworkFoundNumResults = 0;
1873 }
1874 }
1875 break;
1876 case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND:
1877 {
1878 wifi_request_id id;
1879
1880 if (!tbVendor[
1881 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID])
1882 {
1883 /* RequestId is not provided by FW/Driver for this event */
1884 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.",
1885 __FUNCTION__);
1886 id = mRequestId; /* Use the saved mRequestId instead. */
1887 } else {
1888 id = nla_get_u32(
1889 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]
1890 );
1891 /* If this is not for us, use the saved requestId */
1892 if (id != mRequestId) {
1893 ALOGE("%s: Event has Req. ID:%d <> ours:%d",
1894 __FUNCTION__, id, mRequestId);
1895 id = mRequestId;
1896 }
1897 }
1898
1899 ret = gscan_parse_passpoint_network_result(tbVendor);
1900 /* If a parsing error occurred, exit and proceed for cleanup. */
1901 if (ret)
1902 {
1903 ALOGE("%s: gscan_parse_passpoint_network_result"
1904 "returned error: %d.\n", __FUNCTION__, ret);
1905 break;
1906 }
1907 (*mHandler.on_passpoint_network_found)(id,
1908 mPasspointNetId,
1909 mPasspointNetworkFoundResult,
1910 mPasspointAnqpLen,
1911 mPasspointAnqp);
1912 if (mPasspointNetworkFoundResult)
1913 {
1914 free(mPasspointNetworkFoundResult);
1915 mPasspointNetworkFoundResult = NULL;
1916 }
1917 if (mPasspointAnqp)
1918 {
1919 free(mPasspointAnqp);
1920 mPasspointAnqp = NULL;
1921 }
1922 mPasspointNetId = -1;
1923 mPasspointAnqpLen = 0;
1924 }
1925 break;
1926 default:
1927 /* Error case should not happen print log */
1928 ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd);
1929 }
1930
1931 /* A parsing error occurred, do the cleanup of gscan result lists. */
1932 if (ret) {
1933 switch(mSubcmd)
1934 {
1935 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT:
1936 {
1937 free(result);
1938 result = NULL;
1939 }
1940 break;
1941
1942 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND:
1943 {
1944 /* Reset flag and num counter. */
1945 free(mHotlistApFoundResults);
1946 mHotlistApFoundResults = NULL;
1947 mHotlistApFoundMoreData = false;
1948 mHotlistApFoundNumResults = 0;
1949 }
1950 break;
1951
1952 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE:
1953 {
1954 if (mSignificantChangeResults) {
1955 for (i = 0; i < mSignificantChangeNumResults; i++)
1956 {
1957 if (mSignificantChangeResults[i]) {
1958 free(mSignificantChangeResults[i]);
1959 mSignificantChangeResults[i] = NULL;
1960 }
1961 }
1962 free(mSignificantChangeResults);
1963 mSignificantChangeResults = NULL;
1964 }
1965 mSignificantChangeNumResults = 0;
1966 mSignificantChangeMoreData = false;
1967 }
1968 break;
1969
1970 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE:
1971 break;
1972
1973 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT:
1974 break;
1975
1976 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST:
1977 {
1978 /* Reset flag and num counter. */
1979 free(mHotlistApLostResults);
1980 mHotlistApLostResults = NULL;
1981 mHotlistApLostMoreData = false;
1982 mHotlistApLostNumResults = 0;
1983 }
1984 break;
1985
1986 case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND:
1987 {
1988 /* Reset flag and num counter. */
1989 if (mPnoNetworkFoundResults) {
1990 free(mPnoNetworkFoundResults);
1991 mPnoNetworkFoundResults = NULL;
1992 }
1993 mPnoNetworkFoundMoreData = false;
1994 mPnoNetworkFoundNumResults = 0;
1995 }
1996 break;
1997
1998 case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND:
1999 {
2000 if (mPasspointNetworkFoundResult)
2001 {
2002 free(mPasspointNetworkFoundResult);
2003 mPasspointNetworkFoundResult = NULL;
2004 }
2005 if (mPasspointAnqp)
2006 {
2007 free(mPasspointAnqp);
2008 mPasspointAnqp = NULL;
2009 }
2010 mPasspointNetId = -1;
2011 mPasspointAnqpLen = 0;
2012 }
2013 break;
2014
2015 default:
2016 ALOGE("%s: Parsing err handler: wrong GScan subcmd "
2017 "received %d", __FUNCTION__, mSubcmd);
2018 }
2019 }
2020 return NL_SKIP;
2021 }
2022