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. */ 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 40 int GScanCommandEventHandler::get_request_id() 41 { 42 return mRequestId; 43 } 44 45 void GScanCommandEventHandler::set_request_id(int request_id) 46 { 47 mRequestId = request_id; 48 } 49 50 void GScanCommandEventHandler::enableEventHandling() 51 { 52 mEventHandlingEnabled = true; 53 } 54 55 void GScanCommandEventHandler::disableEventHandling() 56 { 57 mEventHandlingEnabled = false; 58 } 59 60 bool GScanCommandEventHandler::isEventHandlingEnabled() 61 { 62 return mEventHandlingEnabled; 63 } 64 65 void GScanCommandEventHandler::setCallbackHandler(GScanCallbackHandler handler) 66 { 67 mHandler = handler; 68 } 69 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 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 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 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 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 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 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 */ 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