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#include "gscan_event_handler.h" 18#include "vendor_definitions.h" 19 20/* This function implements creation of Vendor command event handler. */ 21int GScanCommandEventHandler::create() { 22 int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); 23 if (ret < 0) { 24 return ret; 25 } 26 27 /* Insert the oui in the msg */ 28 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); 29 if (ret < 0) 30 goto out; 31 32 /* Insert the subcmd in the msg */ 33 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); 34 if (ret < 0) 35 goto out; 36out: 37 return ret; 38} 39 40int GScanCommandEventHandler::get_request_id() 41{ 42 return mRequestId; 43} 44 45GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, 46 u32 vendor_id, 47 u32 subcmd, 48 GScanCallbackHandler handler) 49 : WifiVendorCommand(handle, id, vendor_id, subcmd) 50{ 51 int ret = 0; 52 ALOGD("GScanCommandEventHandler %p constructed", this); 53 mRequestId = id; 54 mHandler = handler; 55 mSubCommandId = subcmd; 56 mHotlistApFoundResults = NULL; 57 mHotlistApFoundNumResults = 0; 58 mHotlistApFoundMoreData = false; 59 mSignificantChangeResults = NULL; 60 mSignificantChangeNumResults = 0; 61 mSignificantChangeMoreData = false; 62 63 switch(mSubCommandId) 64 { 65 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START: 66 { 67 /* Register handlers for northbound asychronous scan events. */ 68 ALOGD("%s: wait for GSCAN_RESULTS_AVAILABLE, " 69 "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __func__); 70 ret = registerVendorHandler(mVendor_id, 71 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE) || 72 registerVendorHandler(mVendor_id, 73 QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) || 74 registerVendorHandler(mVendor_id, 75 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT); 76 if (ret < 0) 77 ALOGD("%s: Error in registering handler for " 78 "GSCAN_START. \n", __func__); 79 } 80 break; 81 82 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE: 83 { 84 ret = registerVendorHandler(mVendor_id, 85 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE); 86 if (ret < 0) 87 ALOGD("%s: Error in registering handler for " 88 "GSCAN_SIGNIFICANT_CHANGE. \n", __func__); 89 } 90 break; 91 92 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST: 93 { 94 ret = registerVendorHandler(mVendor_id, 95 QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND); 96 if (ret < 0) 97 ALOGD("%s: Error in registering handler for" 98 " GSCAN_HOTLIST_AP_FOUND. \n", __func__); 99 } 100 break; 101 } 102} 103 104GScanCommandEventHandler::~GScanCommandEventHandler() 105{ 106 ALOGD("GScanCommandEventHandler %p destructor", this); 107 switch(mSubCommandId) 108 { 109 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START: 110 { 111 /* Unregister event handlers. */ 112 ALOGD("%s: Unregister handlers for GSCAN_RESULTS_AVAILABLE, " 113 "FULL_SCAN_RESULT, and SCAN EVENT events. \n", __func__); 114 unregisterVendorHandler(mVendor_id, 115 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE); 116 unregisterVendorHandler(mVendor_id, 117 QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT); 118 unregisterVendorHandler(mVendor_id, 119 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT); 120 } 121 break; 122 123 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE: 124 { 125 unregisterVendorHandler(mVendor_id, 126 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE); 127 } 128 break; 129 130 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST: 131 { 132 unregisterVendorHandler(mVendor_id, 133 QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND); 134 } 135 break; 136 } 137} 138 139static wifi_error gscan_get_hotlist_ap_found_results(u32 num_results, 140 wifi_scan_result *results, 141 u32 starting_index, 142 struct nlattr **tb_vendor) 143{ 144 u32 i = starting_index; 145 struct nlattr *scanResultsInfo; 146 int rem = 0; 147 u32 len = 0; 148 ALOGE("gscan_get_hotlist_ap_found_results: starting counter: %d", i); 149 150 for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ 151 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), 152 rem = nla_len(tb_vendor[ 153 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST 154 ]); 155 nla_ok(scanResultsInfo, rem); 156 scanResultsInfo = nla_next(scanResultsInfo, &(rem))) 157 { 158 struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 159 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 160 (struct nlattr *) nla_data(scanResultsInfo), 161 nla_len(scanResultsInfo), NULL); 162 163 if (! 164 tb2[ 165 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP 166 ]) 167 { 168 ALOGE("gscan_get_hotlist_ap_found_results: " 169 "RESULTS_SCAN_RESULT_TIME_STAMP not found"); 170 return WIFI_ERROR_INVALID_ARGS; 171 } 172 results[i].ts = 173 nla_get_u64( 174 tb2[ 175 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP 176 ]); 177 if (! 178 tb2[ 179 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID 180 ]) 181 { 182 ALOGE("gscan_get_hotlist_ap_found_results: " 183 "RESULTS_SCAN_RESULT_SSID not found"); 184 return WIFI_ERROR_INVALID_ARGS; 185 } 186 len = nla_len(tb2[ 187 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); 188 len = 189 sizeof(results->ssid) <= len ? sizeof(results->ssid) : len; 190 memcpy((void *)&results[i].ssid, 191 nla_data( 192 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); 193 if (! 194 tb2[ 195 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID 196 ]) 197 { 198 ALOGE("gscan_get_hotlist_ap_found_results: " 199 "RESULTS_SCAN_RESULT_BSSID not found"); 200 return WIFI_ERROR_INVALID_ARGS; 201 } 202 len = nla_len( 203 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); 204 len = 205 sizeof(results->bssid) <= len ? sizeof(results->bssid) : len; 206 memcpy(&results[i].bssid, 207 nla_data( 208 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); 209 if (! 210 tb2[ 211 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL 212 ]) 213 { 214 ALOGE("gscan_get_hotlist_ap_found_results: " 215 "RESULTS_SCAN_RESULT_CHANNEL not found"); 216 return WIFI_ERROR_INVALID_ARGS; 217 } 218 results[i].channel = 219 nla_get_u32( 220 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); 221 if (! 222 tb2[ 223 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI 224 ]) 225 { 226 ALOGE("gscan_get_hotlist_ap_found_results: " 227 "RESULTS_SCAN_RESULT_RSSI not found"); 228 return WIFI_ERROR_INVALID_ARGS; 229 } 230 results[i].rssi = 231 nla_get_u32( 232 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); 233 if (! 234 tb2[ 235 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT 236 ]) 237 { 238 ALOGE("gscan_get_hotlist_ap_found_results: " 239 "RESULTS_SCAN_RESULT_RTT not found"); 240 return WIFI_ERROR_INVALID_ARGS; 241 } 242 results[i].rtt = 243 nla_get_u32( 244 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); 245 if (! 246 tb2[ 247 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD 248 ]) 249 { 250 ALOGE("gscan_get_hotlist_ap_found_results: " 251 "RESULTS_SCAN_RESULT_RTT_SD not found"); 252 return WIFI_ERROR_INVALID_ARGS; 253 } 254 results[i].rtt_sd = 255 nla_get_u32( 256 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); 257 258 ALOGE("gscan_get_hotlist_ap_found_results: ts %lld ", results[i].ts); 259 ALOGE("gscan_get_hotlist_ap_found_results: SSID %s ", 260 results[i].ssid) ; 261 ALOGE("gscan_get_hotlist_ap_found_results: " 262 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n", 263 results[i].bssid[0], results[i].bssid[1], results[i].bssid[2], 264 results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]); 265 ALOGE("gscan_get_hotlist_ap_found_results: channel %d ", 266 results[i].channel); 267 ALOGE("gscan_get_hotlist_ap_found_results: rssi %d ", results[i].rssi); 268 ALOGE("gscan_get_hotlist_ap_found_results: rtt %lld ", results[i].rtt); 269 ALOGE("gscan_get_hotlist_ap_found_results: rtt_sd %lld ", 270 results[i].rtt_sd); 271 /* Increment loop index for next record */ 272 i++; 273 } 274 return WIFI_SUCCESS; 275} 276 277static wifi_error gscan_get_significant_change_results(u32 num_results, 278 wifi_significant_change_result **results, 279 u32 starting_index, 280 struct nlattr **tb_vendor) 281{ 282 u32 i = starting_index; 283 int j; 284 int rem = 0; 285 u32 len = 0; 286 struct nlattr *scanResultsInfo; 287 288 ALOGE("gscan_get_significant_change_results: starting counter: %d", i); 289 290 for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ 291 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), 292 rem = nla_len(tb_vendor[ 293 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]); 294 nla_ok(scanResultsInfo, rem); 295 scanResultsInfo = nla_next(scanResultsInfo, &(rem))) 296 { 297 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 298 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 299 (struct nlattr *) nla_data(scanResultsInfo), 300 nla_len(scanResultsInfo), NULL); 301 if (! 302 tb2[ 303 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID 304 ]) 305 { 306 ALOGE("gscan_get_significant_change_results: " 307 "SIGNIFICANT_CHANGE_RESULT_BSSID not found"); 308 return WIFI_ERROR_INVALID_ARGS; 309 } 310 len = nla_len( 311 tb2[ 312 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID] 313 ); 314 len = 315 sizeof(results[i]->bssid) <= len ? sizeof(results[i]->bssid) : len; 316 memcpy(&results[i]->bssid[0], 317 nla_data( 318 tb2[ 319 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]), 320 len); 321 ALOGI("\nsignificant_change_result:%d, BSSID:" 322 "%02x:%02x:%02x:%02x:%02x:%02x \n", i, results[i]->bssid[0], 323 results[i]->bssid[1], results[i]->bssid[2], results[i]->bssid[3], 324 results[i]->bssid[4], results[i]->bssid[5]); 325 326 if (! 327 tb2[ 328 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL 329 ]) 330 { 331 ALOGE("gscan_get_significant_change_results: " 332 "SIGNIFICANT_CHANGE_RESULT_CHANNEL not found"); 333 return WIFI_ERROR_INVALID_ARGS; 334 } 335 results[i]->channel = 336 nla_get_u32( 337 tb2[ 338 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL]); 339 ALOGI("significant_change_result:%d, channel:%d.\n", 340 i, results[i]->channel); 341 342 if (! 343 tb2[ 344 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI 345 ]) 346 { 347 ALOGE("gscan_get_significant_change_results: " 348 "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found"); 349 return WIFI_ERROR_INVALID_ARGS; 350 } 351 results[i]->num_rssi = 352 nla_get_u32( 353 tb2[ 354 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI]); 355 ALOGI("gscan_get_significant_change_results: " 356 "significant_change_result:%d, num_rssi:%d.\n", 357 i, results[i]->num_rssi); 358 359 if (! 360 tb2[ 361 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST 362 ]) 363 { 364 ALOGE("gscan_get_significant_change_results: " 365 "SIGNIFICANT_CHANGE_RESULT_RSSI_LIST not found"); 366 return WIFI_ERROR_INVALID_ARGS; 367 } 368 ALOGI("gscan_get_significant_change_results: before reading the RSSI " 369 "list: num_rssi:%d, size_of_rssi:%d, total size:%d, ", 370 results[i]->num_rssi, 371 sizeof(wifi_rssi), results[i]->num_rssi * sizeof(wifi_rssi)); 372 373 memcpy(&(results[i]->rssi[0]), 374 nla_data( 375 tb2[ 376 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST] 377 ), results[i]->num_rssi * sizeof(wifi_rssi)); 378 379 for (j = 0; j < results[i]->num_rssi; j++) 380 ALOGI(" significant_change_result: %d, rssi[%d]:%d, ", 381 i, j, results[i]->rssi[j]); 382 383 /* Increment loop index to prase next record. */ 384 i++; 385 } 386 return WIFI_SUCCESS; 387} 388 389/* This function will be the main handler for incoming (from driver) GSscan_SUBCMD. 390 * Calls the appropriate callback handler after parsing the vendor data. 391 */ 392int GScanCommandEventHandler::handleEvent(WifiEvent &event) 393{ 394 ALOGI("GScanCommandEventHandler::handleEvent: Got a GSCAN Event" 395 " message from the Driver."); 396 unsigned i=0; 397 int ret = WIFI_SUCCESS; 398 u32 status; 399 wifi_scan_result *result; 400 struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 401 402 WifiVendorCommand::handleEvent(event); 403 404 nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 405 (struct nlattr *)mVendorData, 406 mDataLen, NULL); 407 408 switch(mSubcmd) 409 { 410 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT: 411 { 412 wifi_request_id reqId; 413 u32 len = 0; 414 u32 resultsBufSize = 0; 415 u32 lengthOfInfoElements = 0; 416 417 ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT " 418 "received."); 419 420 if (!tbVendor[ 421 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) 422 { 423 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.", 424 __func__); 425 ret = WIFI_ERROR_INVALID_ARGS; 426 break; 427 } 428 reqId = nla_get_u32( 429 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] 430 ); 431 /* If this is not for us, just ignore it. */ 432 if (reqId != mRequestId) { 433 ALOGE("%s: Event has Req. ID:%d <> Ours:%d, ignore it.", 434 __func__, reqId, mRequestId); 435 break; 436 } 437 438 /* Parse and extract the results. */ 439 if (! 440 tbVendor[ 441 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH 442 ]) 443 { 444 ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __func__); 445 ret = WIFI_ERROR_INVALID_ARGS; 446 break; 447 } 448 lengthOfInfoElements = 449 nla_get_u32( 450 tbVendor[ 451 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]); 452 ALOGI("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d", 453 __func__, lengthOfInfoElements); 454 resultsBufSize = 455 lengthOfInfoElements + sizeof(wifi_scan_result); 456 result = (wifi_scan_result *) malloc (resultsBufSize); 457 if (!result) { 458 ALOGE("%s: Failed to alloc memory for result struct. Exit.\n", 459 __func__); 460 ret = WIFI_ERROR_OUT_OF_MEMORY; 461 break; 462 } 463 memset(result, 0, resultsBufSize); 464 465 result->ie_length = lengthOfInfoElements; 466 467 /* Extract and fill out the wifi_scan_result struct. */ 468 if (! 469 tbVendor[ 470 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP 471 ]) 472 { 473 ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found", 474 __func__); 475 ret = WIFI_ERROR_INVALID_ARGS; 476 break; 477 } 478 result->ts = 479 nla_get_u64( 480 tbVendor[ 481 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP 482 ]); 483 484 if (! 485 tbVendor[ 486 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID 487 ]) 488 { 489 ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __func__); 490 ret = WIFI_ERROR_INVALID_ARGS; 491 break; 492 } 493 len = nla_len(tbVendor[ 494 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); 495 len = 496 sizeof(result->ssid) <= len ? sizeof(result->ssid) : len; 497 memcpy((void *)&result->ssid, 498 nla_data( 499 tbVendor[ 500 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); 501 502 if (! 503 tbVendor[ 504 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID 505 ]) 506 { 507 ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __func__); 508 ret = WIFI_ERROR_INVALID_ARGS; 509 break; 510 } 511 len = nla_len( 512 tbVendor[ 513 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); 514 len = 515 sizeof(result->bssid) <= len ? sizeof(result->bssid) : len; 516 memcpy(&result->bssid, 517 nla_data( 518 tbVendor[ 519 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); 520 521 if (! 522 tbVendor[ 523 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL 524 ]) 525 { 526 ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __func__); 527 ret = WIFI_ERROR_INVALID_ARGS; 528 break; 529 } 530 result->channel = 531 nla_get_u32( 532 tbVendor[ 533 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); 534 535 if (! 536 tbVendor[ 537 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI 538 ]) 539 { 540 ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __func__); 541 ret = WIFI_ERROR_INVALID_ARGS; 542 break; 543 } 544 result->rssi = 545 nla_get_u32( 546 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI] 547 ); 548 549 if (! 550 tbVendor[ 551 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT 552 ]) 553 { 554 ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __func__); 555 ret = WIFI_ERROR_INVALID_ARGS; 556 break; 557 } 558 result->rtt = 559 nla_get_u32( 560 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); 561 562 if (! 563 tbVendor[ 564 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD 565 ]) 566 { 567 ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __func__); 568 ret = WIFI_ERROR_INVALID_ARGS; 569 break; 570 } 571 result->rtt_sd = 572 nla_get_u32( 573 tbVendor[ 574 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); 575 576 if (! 577 tbVendor[ 578 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]) 579 { 580 ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found", 581 __func__); 582 ret = WIFI_ERROR_INVALID_ARGS; 583 break; 584 } 585 result->beacon_period = 586 nla_get_u16( 587 tbVendor[ 588 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]); 589 590 if (! 591 tbVendor[ 592 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY 593 ]) 594 { 595 ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __func__); 596 ret = WIFI_ERROR_INVALID_ARGS; 597 break; 598 } 599 result->capability = 600 nla_get_u16( 601 tbVendor[ 602 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]); 603 604 if (! 605 tbVendor[ 606 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA 607 ]) 608 { 609 ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __func__); 610 ret = WIFI_ERROR_INVALID_ARGS; 611 break; 612 } 613 memcpy(&(result->ie_data[0]), 614 nla_data(tbVendor[ 615 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]), 616 lengthOfInfoElements); 617 618 ALOGE("handleEvent:FULL_SCAN_RESULTS: ts %lld ", result->ts); 619 ALOGE("handleEvent:FULL_SCAN_RESULTS: SSID %s ", result->ssid) ; 620 ALOGE("handleEvent:FULL_SCAN_RESULTS: " 621 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n", 622 result->bssid[0], result->bssid[1], result->bssid[2], 623 result->bssid[3], result->bssid[4], result->bssid[5]); 624 ALOGE("handleEvent:FULL_SCAN_RESULTS: channel %d ", 625 result->channel); 626 ALOGE("handleEvent:FULL_SCAN_RESULTS: rssi %d ", result->rssi); 627 ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt %lld ", result->rtt); 628 ALOGE("handleEvent:FULL_SCAN_RESULTS: rtt_sd %lld ", 629 result->rtt_sd); 630 ALOGE("handleEvent:FULL_SCAN_RESULTS: beacon period %d ", 631 result->beacon_period); 632 ALOGE("handleEvent:FULL_SCAN_RESULTS: capability %d ", 633 result->capability); 634 ALOGE("handleEvent:FULL_SCAN_RESULTS: IE length %d ", 635 result->ie_length); 636 637 ALOGE("%s: Invoking the callback. \n", __func__); 638 if (mHandler.on_full_scan_result) { 639 (*mHandler.on_full_scan_result)(reqId, result); 640 /* Reset flag and num counter. */ 641 free(result); 642 result = NULL; 643 } 644 } 645 break; 646 647 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE: 648 { 649 wifi_request_id id; 650 u32 numResults = 0; 651 652 ALOGD("Event " 653 "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE " 654 "received."); 655 656 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) { 657 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID" 658 "not found. Exit", __func__); 659 ret = WIFI_ERROR_INVALID_ARGS; 660 break; 661 } 662 id = nla_get_u32( 663 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] 664 ); 665 /* If this is not for us, then ignore it. */ 666 if (id != mRequestId) { 667 ALOGE("%s: Event has Req. ID:%d <> ours:%d", 668 __func__, id, mRequestId); 669 break; 670 } 671 if (!tbVendor[ 672 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { 673 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found", 674 __func__); 675 ret = WIFI_ERROR_INVALID_ARGS; 676 break; 677 } 678 numResults = nla_get_u32(tbVendor[ 679 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); 680 ALOGE("%s: number of results:%d", __func__, numResults); 681 682 /* Invoke the callback func to report the number of results. */ 683 ALOGE("%s: Calling on_scan_results_available handler", 684 __func__); 685 if (!mHandler.on_scan_results_available) { 686 break; 687 } 688 (*mHandler.on_scan_results_available)(id, numResults); 689 } 690 break; 691 692 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND: 693 { 694 wifi_request_id id; 695 u32 resultsBufSize = 0; 696 u32 numResults = 0; 697 u32 startingIndex, sizeOfObtainedResults; 698 699 ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND " 700 "received."); 701 702 id = nla_get_u32( 703 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] 704 ); 705 /* If this is not for us, just ignore it. */ 706 if (id != mRequestId) { 707 ALOGE("%s: Event has Req. ID:%d <> ours:%d", 708 __func__, id, mRequestId); 709 break; 710 } 711 if (!tbVendor[ 712 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { 713 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found", 714 __func__); 715 ret = WIFI_ERROR_INVALID_ARGS; 716 break; 717 } 718 numResults = nla_get_u32(tbVendor[ 719 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); 720 ALOGE("%s: number of results:%d", __func__, numResults); 721 722 /* Get the memory size of previous fragments, if any. */ 723 sizeOfObtainedResults = mHotlistApFoundNumResults * 724 sizeof(wifi_scan_result); 725 726 mHotlistApFoundNumResults += numResults; 727 resultsBufSize += mHotlistApFoundNumResults * 728 sizeof(wifi_scan_result); 729 730 /* Check if this chunck of scan results is a continuation of 731 * a previous one. 732 */ 733 if (mHotlistApFoundMoreData) { 734 mHotlistApFoundResults = (wifi_scan_result *) 735 realloc (mHotlistApFoundResults, resultsBufSize); 736 } else { 737 mHotlistApFoundResults = (wifi_scan_result *) 738 malloc (resultsBufSize); 739 } 740 741 if (!mHotlistApFoundResults) { 742 ALOGE("%s: Failed to alloc memory for results array. Exit.\n", 743 __func__); 744 ret = WIFI_ERROR_OUT_OF_MEMORY; 745 break; 746 } 747 /* Initialize the newly allocated memory area with 0. */ 748 memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0, 749 resultsBufSize - sizeOfObtainedResults); 750 751 ALOGE("%s: Num of AP FOUND results = %d. \n", __func__, 752 mHotlistApFoundNumResults); 753 754 /* To support fragmentation from firmware, monitor the 755 * MORE_DTATA flag and cache results until MORE_DATA = 0. 756 * Only then we can pass on the results to framework through 757 * the callback function. 758 */ 759 if (!tbVendor[ 760 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { 761 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not" 762 " found", __func__); 763 ret = WIFI_ERROR_INVALID_ARGS; 764 break; 765 } else { 766 mHotlistApFoundMoreData = nla_get_u8( 767 tbVendor[ 768 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); 769 ALOGE("%s: More data = %d. \n", 770 __func__, mHotlistApFoundMoreData); 771 } 772 773 ALOGE("%s: Extract hotlist_ap_found results.\n", __func__); 774 startingIndex = mHotlistApFoundNumResults - numResults; 775 ALOGE("%s: starting_index:%d", 776 __func__, startingIndex); 777 ret = gscan_get_hotlist_ap_found_results(numResults, 778 mHotlistApFoundResults, 779 startingIndex, 780 tbVendor); 781 /* If a parsing error occurred, exit and proceed for cleanup. */ 782 if (ret) 783 break; 784 /* Send the results if no more result data fragments are expected. */ 785 if (!mHotlistApFoundMoreData) { 786 (*mHandler.on_hotlist_ap_found)(id, 787 mHotlistApFoundNumResults, 788 mHotlistApFoundResults); 789 /* Reset flag and num counter. */ 790 free(mHotlistApFoundResults); 791 mHotlistApFoundResults = NULL; 792 mHotlistApFoundMoreData = false; 793 mHotlistApFoundNumResults = 0; 794 } 795 } 796 break; 797 798 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE: 799 { 800 wifi_request_id reqId; 801 u32 numResults = 0, sizeOfObtainedResults; 802 u32 startingIndex, index = 0; 803 struct nlattr *scanResultsInfo; 804 int rem = 0; 805 806 ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE " 807 "received."); 808 809 if (!tbVendor[ 810 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) 811 { 812 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.", 813 __func__); 814 ret = WIFI_ERROR_INVALID_ARGS; 815 break; 816 } 817 reqId = nla_get_u32( 818 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] 819 ); 820 /* If this is not for us, just ignore it. */ 821 if (reqId != mRequestId) { 822 ALOGE("%s: Event has Req. ID:%d <> ours:%d", 823 __func__, reqId, mRequestId); 824 break; 825 } 826 if (!tbVendor[ 827 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) 828 { 829 ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found." 830 "Exit.", __func__); 831 ret = WIFI_ERROR_INVALID_ARGS; 832 break; 833 } 834 numResults = nla_get_u32(tbVendor[ 835 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); 836 /* Get the memory size of previous fragments, if any. */ 837 sizeOfObtainedResults = sizeof(wifi_significant_change_result *) * 838 mSignificantChangeNumResults; 839 840 index = mSignificantChangeNumResults; 841 mSignificantChangeNumResults += numResults; 842 /* 843 * Check if this chunck of wifi_significant_change results is a 844 * continuation of a previous one. 845 */ 846 if (mSignificantChangeMoreData) { 847 mSignificantChangeResults = 848 (wifi_significant_change_result **) 849 realloc (mSignificantChangeResults, 850 sizeof(wifi_significant_change_result *) * 851 mSignificantChangeNumResults); 852 } else { 853 mSignificantChangeResults = 854 (wifi_significant_change_result **) 855 malloc (sizeof(wifi_significant_change_result *) * 856 mSignificantChangeNumResults); 857 } 858 859 if (!mSignificantChangeResults) { 860 ALOGE("%s: Failed to alloc memory for results array. Exit.\n", 861 __func__); 862 ret = WIFI_ERROR_OUT_OF_MEMORY; 863 break; 864 } 865 /* Initialize the newly allocated memory area with 0. */ 866 memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0, 867 sizeof(wifi_significant_change_result *) * 868 numResults); 869 ALOGD("%s: mSignificantChangeMoreData = %d", 870 __func__, mSignificantChangeMoreData); 871 872 for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[ 873 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), 874 rem = nla_len(tbVendor[ 875 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]); 876 nla_ok(scanResultsInfo, rem); 877 scanResultsInfo = nla_next(scanResultsInfo, &(rem))) 878 { 879 u32 num_rssi = 0; 880 u32 resultsBufSize = 0; 881 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 882 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 883 (struct nlattr *) nla_data(scanResultsInfo), 884 nla_len(scanResultsInfo), NULL); 885 if (!tb2[ 886 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI 887 ]) 888 { 889 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_" 890 "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. " 891 "Exit.", __func__); 892 ret = WIFI_ERROR_INVALID_ARGS; 893 break; 894 } 895 num_rssi = nla_get_u32(tb2[ 896 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI 897 ]); 898 resultsBufSize = sizeof(wifi_significant_change_result) + 899 num_rssi * sizeof(wifi_rssi); 900 mSignificantChangeResults[index] = 901 (wifi_significant_change_result *) malloc (resultsBufSize); 902 903 if (!mSignificantChangeResults[index]) { 904 ALOGE("%s: Failed to alloc memory for results array. Exit.\n", 905 __func__); 906 ret = WIFI_ERROR_OUT_OF_MEMORY; 907 break; 908 } 909 /* Initialize the newly allocated memory area with 0. */ 910 memset((u8 *)mSignificantChangeResults[index], 911 0, resultsBufSize); 912 913 ALOGE("%s: For Significant Change results[%d], num_rssi:%d\n", 914 __func__, index, num_rssi); 915 index++; 916 } 917 918 ALOGE("%s: Extract significant change results.\n", __func__); 919 startingIndex = 920 mSignificantChangeNumResults - numResults; 921 ret = gscan_get_significant_change_results(numResults, 922 mSignificantChangeResults, 923 startingIndex, 924 tbVendor); 925 /* If a parsing error occurred, exit and proceed for cleanup. */ 926 if (ret) 927 break; 928 /* To support fragmentation from firmware, monitor the 929 * MORE_DTATA flag and cache results until MORE_DATA = 0. 930 * Only then we can pass on the results to framework through 931 * the callback function. 932 */ 933 if (!tbVendor[ 934 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { 935 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not" 936 " found. Stop parsing and exit.", __func__); 937 break; 938 } 939 mSignificantChangeMoreData = nla_get_u8( 940 tbVendor[ 941 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); 942 ALOGE("%s: More data = %d. \n", 943 __func__, mSignificantChangeMoreData); 944 945 /* Send the results if no more result fragments are expected */ 946 if (!mSignificantChangeMoreData) { 947 ALOGE("%s: Invoking the callback. \n", __func__); 948 (*mHandler.on_significant_change)(reqId, 949 mSignificantChangeNumResults, 950 mSignificantChangeResults); 951 /* Reset flag and num counter. */ 952 for (index = 0; index < mSignificantChangeNumResults; index++) 953 { 954 free(mSignificantChangeResults[index]); 955 mSignificantChangeResults[index] = NULL; 956 } 957 free(mSignificantChangeResults); 958 mSignificantChangeResults = NULL; 959 mSignificantChangeNumResults = 0; 960 mSignificantChangeMoreData = false; 961 } 962 } 963 break; 964 965 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT: 966 { 967 wifi_scan_event scanEvent; 968 u32 scanEventStatus = 0; 969 wifi_request_id reqId; 970 971 ALOGD("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT " 972 "received."); 973 974 if (!tbVendor[ 975 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) 976 { 977 ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.", 978 __func__); 979 ret = WIFI_ERROR_INVALID_ARGS; 980 break; 981 } 982 reqId = nla_get_u32( 983 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] 984 ); 985 /* If this is not for us, just ignore it. */ 986 if (reqId != mRequestId) { 987 ALOGE("%s: Event has Req. ID:%d <> ours:%d", 988 __func__, reqId, mRequestId); 989 break; 990 } 991 992 if (!tbVendor[ 993 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) { 994 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not" 995 " found. Stop parsing and exit.", __func__); 996 break; 997 } 998 scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[ 999 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]); 1000 1001 if (!tbVendor[ 1002 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]) { 1003 ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_STATUS not" 1004 " found. Stop parsing and exit.", __func__); 1005 break; 1006 } 1007 scanEventStatus = nla_get_u32(tbVendor[ 1008 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS]); 1009 1010 ALOGE("%s: Scan event type: %d, status = %d. \n", __func__, 1011 scanEvent, scanEventStatus); 1012 /* Send the results if no more result fragments are expected. */ 1013 (*mHandler.on_scan_event)(scanEvent, scanEventStatus); 1014 } 1015 break; 1016 1017 default: 1018 /* Error case should not happen print log */ 1019 ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd); 1020 } 1021 1022 /* A parsing error occurred, do the cleanup of gscan result lists. */ 1023 if (ret) { 1024 switch(mSubcmd) 1025 { 1026 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT: 1027 { 1028 free(result); 1029 result = NULL; 1030 } 1031 break; 1032 1033 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND: 1034 { 1035 /* Reset flag and num counter. */ 1036 free(mHotlistApFoundResults); 1037 mHotlistApFoundResults = NULL; 1038 mHotlistApFoundMoreData = false; 1039 mHotlistApFoundNumResults = 0; 1040 } 1041 break; 1042 1043 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE: 1044 { 1045 for (i = 0; i < mSignificantChangeNumResults; i++) 1046 { 1047 if (mSignificantChangeResults[i]) { 1048 free(mSignificantChangeResults[i]); 1049 mSignificantChangeResults[i] = NULL; 1050 } 1051 } 1052 free(mSignificantChangeResults); 1053 mSignificantChangeResults = NULL; 1054 mSignificantChangeNumResults = 0; 1055 mSignificantChangeMoreData = false; 1056 } 1057 break; 1058 1059 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE: 1060 break; 1061 1062 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT: 1063 break; 1064 1065 default: 1066 ALOGE("%s: Parsing err handler: wrong GScan subcmd " 1067 "received %d", __func__, mSubcmd); 1068 } 1069 } 1070 return NL_SKIP; 1071} 1072