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