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