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