1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sync.h" 18 #define LOG_TAG "WifiHAL" 19 #include <utils/Log.h> 20 #include <time.h> 21 22 #include "common.h" 23 #include "cpp_bindings.h" 24 #include "gscancommand.h" 25 #include "gscan_event_handler.h" 26 27 #define GSCAN_EVENT_WAIT_TIME_SECONDS 4 28 29 /* Used to handle gscan command events from driver/firmware. */ 30 GScanCommandEventHandler *GScanStartCmdEventHandler = NULL; 31 GScanCommandEventHandler *GScanSetBssidHotlistCmdEventHandler = NULL; 32 GScanCommandEventHandler *GScanSetSignificantChangeCmdEventHandler = NULL; 33 34 /* Implementation of the API functions exposed in gscan.h */ 35 wifi_error wifi_get_valid_channels(wifi_interface_handle handle, 36 int band, int max_channels, wifi_channel *channels, int *num_channels) 37 { 38 int requestId, ret = 0; 39 GScanCommand *gScanCommand; 40 struct nlattr *nlData; 41 interface_info *ifaceInfo = getIfaceInfo(handle); 42 wifi_handle wifiHandle = getWifiHandle(handle); 43 44 if (channels == NULL) { 45 ALOGE("%s: NULL channels pointer provided. Exit.", 46 __func__); 47 return WIFI_ERROR_INVALID_ARGS; 48 } 49 50 /* No request id from caller, so generate one and pass it on to the driver. 51 * Generate one randomly. 52 */ 53 srand( time(NULL) ); 54 requestId = rand(); 55 56 gScanCommand = new GScanCommand( 57 wifiHandle, 58 requestId, 59 OUI_QCA, 60 QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS); 61 if (gScanCommand == NULL) { 62 ALOGE("%s: Error GScanCommand NULL", __func__); 63 return WIFI_ERROR_UNKNOWN; 64 } 65 /* Create the NL message. */ 66 ret = gScanCommand->create(); 67 if (ret < 0) 68 goto cleanup; 69 70 /* Set the interface Id of the message. */ 71 ret = gScanCommand->set_iface_id(ifaceInfo->name); 72 if (ret < 0) 73 goto cleanup; 74 75 /* Add the vendor specific attributes for the NL command. */ 76 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 77 if (!nlData) 78 goto cleanup; 79 80 if (gScanCommand->put_u32( 81 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 82 requestId) || 83 gScanCommand->put_u32( 84 QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND, 85 band) || 86 gScanCommand->put_u32( 87 QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS, 88 max_channels) ) 89 { 90 goto cleanup; 91 } 92 gScanCommand->attr_end(nlData); 93 /* Populate the input received from caller/framework. */ 94 gScanCommand->setMaxChannels(max_channels); 95 gScanCommand->setChannels(channels); 96 gScanCommand->setNumChannelsPtr(num_channels); 97 98 /* Send the msg and wait for a response. */ 99 ret = gScanCommand->requestResponse(); 100 if (ret) { 101 ALOGE("%s: Error %d happened. ", __func__, ret); 102 } 103 104 cleanup: 105 ALOGI("%s: Delete object.", __func__); 106 delete gScanCommand; 107 return (wifi_error)ret; 108 } 109 110 void get_gscan_capabilities_cb(int status, wifi_gscan_capabilities capa) 111 { 112 ALOGD("%s: Status = %d.", __func__, status); 113 ALOGD("%s: Capabilities. max_ap_cache_per_scan:%d, " 114 "max_bssid_history_entries:%d, max_hotlist_aps:%d, " 115 "max_rssi_sample_size:%d, max_scan_buckets:%d, " 116 "max_scan_cache_size:%d, max_scan_reporting_threshold:%d, " 117 "max_significant_wifi_change_aps:%d.", 118 __func__, capa.max_ap_cache_per_scan, 119 capa.max_bssid_history_entries, 120 capa.max_hotlist_aps, capa.max_rssi_sample_size, 121 capa.max_scan_buckets, 122 capa.max_scan_cache_size, capa.max_scan_reporting_threshold, 123 capa.max_significant_wifi_change_aps); 124 } 125 126 wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, 127 wifi_gscan_capabilities *capabilities) 128 { 129 int requestId, ret = 0; 130 GScanCommand *gScanCommand; 131 struct nlattr *nlData; 132 wifi_gscan_capabilities tCapabilities; 133 interface_info *ifaceInfo = getIfaceInfo(handle); 134 wifi_handle wifiHandle = getWifiHandle(handle); 135 136 if (capabilities == NULL) { 137 ALOGE("%s: NULL capabilities pointer provided. Exit.", 138 __func__); 139 return WIFI_ERROR_INVALID_ARGS; 140 } 141 142 /* No request id from caller, so generate one and pass it on to the driver. 143 * Generate it randomly. 144 */ 145 srand(time(NULL)); 146 requestId = rand(); 147 148 gScanCommand = new GScanCommand( 149 wifiHandle, 150 requestId, 151 OUI_QCA, 152 QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES); 153 if (gScanCommand == NULL) { 154 ALOGE("%s: Error GScanCommand NULL", __func__); 155 return WIFI_ERROR_UNKNOWN; 156 } 157 158 GScanCallbackHandler callbackHandler; 159 memset(&callbackHandler, 0, sizeof(callbackHandler)); 160 callbackHandler.get_capabilities = get_gscan_capabilities_cb; 161 162 ret = gScanCommand->setCallbackHandler(callbackHandler); 163 if (ret < 0) 164 goto cleanup; 165 166 /* Create the NL message. */ 167 ret = gScanCommand->create(); 168 if (ret < 0) 169 goto cleanup; 170 171 /* Set the interface Id of the message. */ 172 ret = gScanCommand->set_iface_id(ifaceInfo->name); 173 if (ret < 0) 174 goto cleanup; 175 176 /* Add the vendor specific attributes for the NL command. */ 177 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 178 if (!nlData) 179 goto cleanup; 180 181 ret = gScanCommand->put_u32( 182 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 183 requestId); 184 if (ret < 0) 185 goto cleanup; 186 187 gScanCommand->attr_end(nlData); 188 ret = gScanCommand->allocRspParams(eGScanGetCapabilitiesRspParams); 189 if (ret != 0) { 190 ALOGE("%s: Failed to allocate memory fo response struct. Error:%d", 191 __func__, ret); 192 goto cleanup; 193 } 194 195 gScanCommand->waitForRsp(true); 196 ret = gScanCommand->requestEvent(); 197 if (ret != 0) { 198 ALOGE("%s: requestEvent Error:%d",__func__, ret); 199 goto cleanup; 200 } 201 202 gScanCommand->getGetCapabilitiesRspParams(capabilities, (u32 *)&ret); 203 204 cleanup: 205 gScanCommand->freeRspParams(eGScanGetCapabilitiesRspParams); 206 ALOGI("%s: Delete object.", __func__); 207 delete gScanCommand; 208 return (wifi_error)ret; 209 } 210 211 void start_gscan_cb(int status) 212 { 213 ALOGD("%s: Status = %d.", __func__, status); 214 } 215 216 wifi_error wifi_start_gscan(wifi_request_id id, 217 wifi_interface_handle iface, 218 wifi_scan_cmd_params params, 219 wifi_scan_result_handler handler) 220 { 221 int ret = 0; 222 u32 i, j; 223 GScanCommand *gScanCommand; 224 struct nlattr *nlData; 225 interface_info *ifaceInfo = getIfaceInfo(iface); 226 wifi_handle wifiHandle = getWifiHandle(iface); 227 u32 num_scan_buckets, numChannelSpecs; 228 wifi_scan_bucket_spec bucketSpec; 229 struct nlattr *nlBuckectSpecList; 230 231 /* Check if a similar request to start gscan was made earlier. 232 * Right now we don't differentiate between the case where (i) the new 233 * Request Id is different from the current one vs (ii) case where both 234 * new and Request IDs are the same. 235 */ 236 if (GScanStartCmdEventHandler) { 237 if (id == GScanStartCmdEventHandler->get_request_id()) { 238 ALOGE("wifi_start_gscan(): GSCAN Start for request Id %d is still " 239 "running. Exit", id); 240 return WIFI_ERROR_TOO_MANY_REQUESTS; 241 } else { 242 ALOGE("wifi_start_gscan(): GSCAN Start for a different request " 243 "Id %d is requested. Not supported. Exit", id); 244 return WIFI_ERROR_NOT_SUPPORTED; 245 } 246 } 247 248 gScanCommand = new GScanCommand( 249 wifiHandle, 250 id, 251 OUI_QCA, 252 QCA_NL80211_VENDOR_SUBCMD_GSCAN_START); 253 if (gScanCommand == NULL) { 254 ALOGE("wifi_start_gscan(): Error GScanCommand NULL"); 255 return WIFI_ERROR_UNKNOWN; 256 } 257 258 GScanCallbackHandler callbackHandler; 259 memset(&callbackHandler, 0, sizeof(callbackHandler)); 260 callbackHandler.start = start_gscan_cb; 261 262 ret = gScanCommand->setCallbackHandler(callbackHandler); 263 if (ret < 0) 264 goto cleanup; 265 266 /* Create the NL message. */ 267 ret = gScanCommand->create(); 268 if (ret < 0) 269 goto cleanup; 270 271 /* Set the interface Id of the message. */ 272 ret = gScanCommand->set_iface_id(ifaceInfo->name); 273 if (ret < 0) 274 goto cleanup; 275 276 /* Add the vendor specific attributes for the NL command. */ 277 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 278 if (!nlData) 279 goto cleanup; 280 281 num_scan_buckets = (unsigned int)params.num_buckets > MAX_BUCKETS ? 282 MAX_BUCKETS : params.num_buckets; 283 284 if (gScanCommand->put_u32( 285 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 286 id) || 287 gScanCommand->put_u32( 288 QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD, 289 params.base_period) || 290 gScanCommand->put_u32( 291 QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN, 292 params.max_ap_per_scan) || 293 gScanCommand->put_u8( 294 QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD, 295 params.report_threshold) || 296 gScanCommand->put_u8( 297 QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS, 298 num_scan_buckets)) 299 { 300 goto cleanup; 301 } 302 303 nlBuckectSpecList = 304 gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC); 305 /* Add NL attributes for scan bucket specs . */ 306 for (i = 0; i < num_scan_buckets; i++) { 307 bucketSpec = params.buckets[i]; 308 numChannelSpecs = (unsigned int)bucketSpec.num_channels > MAX_CHANNELS ? 309 MAX_CHANNELS : bucketSpec.num_channels; 310 struct nlattr *nlBucketSpec = gScanCommand->attr_start(i); 311 if (gScanCommand->put_u8( 312 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX, 313 bucketSpec.bucket) || 314 gScanCommand->put_u8( 315 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND, 316 bucketSpec.band) || 317 gScanCommand->put_u32( 318 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD, 319 bucketSpec.period) || 320 gScanCommand->put_u8( 321 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS, 322 bucketSpec.report_events) || 323 gScanCommand->put_u32( 324 QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS, 325 numChannelSpecs)) 326 { 327 goto cleanup; 328 } 329 330 struct nlattr *nl_channelSpecList = 331 gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC); 332 333 /* Add NL attributes for scan channel specs . */ 334 for (j = 0; j < numChannelSpecs; j++) { 335 struct nlattr *nl_channelSpec = gScanCommand->attr_start(j); 336 wifi_scan_channel_spec channel_spec = bucketSpec.channels[j]; 337 338 if ( gScanCommand->put_u32( 339 QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL, 340 channel_spec.channel) || 341 gScanCommand->put_u32( 342 QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME, 343 channel_spec.dwellTimeMs) || 344 gScanCommand->put_u8( 345 QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE, 346 channel_spec.passive) ) 347 { 348 goto cleanup; 349 } 350 351 gScanCommand->attr_end(nl_channelSpec); 352 } 353 gScanCommand->attr_end(nl_channelSpecList); 354 gScanCommand->attr_end(nlBucketSpec); 355 } 356 gScanCommand->attr_end(nlBuckectSpecList); 357 358 gScanCommand->attr_end(nlData); 359 360 ret = gScanCommand->allocRspParams(eGScanStartRspParams); 361 if (ret != 0) { 362 ALOGE("wifi_start_gscan(): Failed to allocate memory to the response " 363 "struct. Error:%d", ret); 364 goto cleanup; 365 } 366 367 /* Set the callback handler functions for related events. */ 368 callbackHandler.on_scan_results_available = 369 handler.on_scan_results_available; 370 callbackHandler.on_full_scan_result = handler.on_full_scan_result; 371 callbackHandler.on_scan_event = handler.on_scan_event; 372 /* Create an object to handle the related events from firmware/driver. */ 373 GScanStartCmdEventHandler = new GScanCommandEventHandler( 374 wifiHandle, 375 id, 376 OUI_QCA, 377 QCA_NL80211_VENDOR_SUBCMD_GSCAN_START, 378 callbackHandler); 379 if (GScanStartCmdEventHandler == NULL) { 380 ALOGE("wifi_start_gscan(): Error GScanStartCmdEventHandler NULL"); 381 ret = WIFI_ERROR_UNKNOWN; 382 goto cleanup; 383 } 384 385 gScanCommand->waitForRsp(true); 386 ret = gScanCommand->requestEvent(); 387 if (ret != 0) { 388 ALOGE("wifi_start_gscan(): requestEvent Error:%d", ret); 389 goto cleanup; 390 } 391 392 gScanCommand->getStartGScanRspParams((u32 *)&ret); 393 if (ret != 0) 394 { 395 goto cleanup; 396 } 397 398 cleanup: 399 gScanCommand->freeRspParams(eGScanStartRspParams); 400 ALOGI("wifi_start_gscan(): Delete object."); 401 delete gScanCommand; 402 /* Delete the command event handler object if ret != 0 */ 403 if (ret && GScanStartCmdEventHandler) { 404 ALOGI("wifi_start_gscan(): Error ret:%d, delete event handler object.", 405 ret); 406 delete GScanStartCmdEventHandler; 407 GScanStartCmdEventHandler = NULL; 408 } 409 return (wifi_error)ret; 410 411 } 412 413 void stop_gscan_cb(int status) 414 { 415 ALOGD("%s: Status = %d.", __func__, status); 416 } 417 418 wifi_error wifi_stop_gscan(wifi_request_id id, 419 wifi_interface_handle iface) 420 { 421 int ret = 0; 422 GScanCommand *gScanCommand; 423 struct nlattr *nlData; 424 425 interface_info *ifaceInfo = getIfaceInfo(iface); 426 wifi_handle wifiHandle = getWifiHandle(iface); 427 428 ALOGI("Stopping GScan, halHandle = %p", wifiHandle); 429 430 if (GScanStartCmdEventHandler) { 431 if (id != GScanStartCmdEventHandler->get_request_id()) { 432 ALOGE("wifi_stop_gscan: GSCAN Stop requested for request Id %d " 433 "not matching that of existing GScan Start:%d. Exit", 434 id, GScanStartCmdEventHandler->get_request_id()); 435 return WIFI_ERROR_INVALID_REQUEST_ID; 436 } 437 } else { 438 ALOGE("wifi_stop_gscan: GSCAN isn't running or already stopped. " 439 "Nothing to do. Exit"); 440 return WIFI_ERROR_NOT_AVAILABLE; 441 } 442 443 gScanCommand = new GScanCommand( 444 wifiHandle, 445 id, 446 OUI_QCA, 447 QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP); 448 if (gScanCommand == NULL) { 449 ALOGE("%s: Error GScanCommand NULL", __func__); 450 return WIFI_ERROR_UNKNOWN; 451 } 452 453 GScanCallbackHandler callbackHandler; 454 memset(&callbackHandler, 0, sizeof(callbackHandler)); 455 callbackHandler.stop = stop_gscan_cb; 456 457 ret = gScanCommand->setCallbackHandler(callbackHandler); 458 if (ret < 0) 459 goto cleanup; 460 461 /* Create the NL message. */ 462 ret = gScanCommand->create(); 463 if (ret < 0) 464 goto cleanup; 465 466 /* Set the interface Id of the message. */ 467 ret = gScanCommand->set_iface_id(ifaceInfo->name); 468 if (ret < 0) 469 goto cleanup; 470 471 /* Add the vendor specific attributes for the NL command. */ 472 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 473 if (!nlData) 474 goto cleanup; 475 476 ret = gScanCommand->put_u32( 477 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 478 id); 479 if (ret < 0) 480 goto cleanup; 481 482 gScanCommand->attr_end(nlData); 483 484 ret = gScanCommand->allocRspParams(eGScanStopRspParams); 485 if (ret != 0) { 486 ALOGE("%s: Failed to allocate memory to the response struct. " 487 "Error:%d", __func__, ret); 488 goto cleanup; 489 } 490 491 gScanCommand->waitForRsp(true); 492 ret = gScanCommand->requestEvent(); 493 if (ret != 0) { 494 ALOGE("%s: requestEvent Error:%d",__func__, ret); 495 goto cleanup; 496 } 497 498 gScanCommand->getStopGScanRspParams((u32 *)&ret); 499 if (ret != 0) 500 { 501 goto cleanup; 502 } 503 504 /* Delete different GSCAN event handlers for the specified Request ID. */ 505 if (GScanStartCmdEventHandler) { 506 delete GScanStartCmdEventHandler; 507 GScanStartCmdEventHandler = NULL; 508 } 509 510 cleanup: 511 gScanCommand->freeRspParams(eGScanStopRspParams); 512 ALOGI("%s: Delete object.", __func__); 513 delete gScanCommand; 514 return (wifi_error)ret; 515 } 516 517 void set_bssid_hotlist_cb(int status) 518 { 519 ALOGD("%s: Status = %d.", __func__, status); 520 } 521 522 /* Set the GSCAN BSSID Hotlist. */ 523 wifi_error wifi_set_bssid_hotlist(wifi_request_id id, 524 wifi_interface_handle iface, 525 wifi_bssid_hotlist_params params, 526 wifi_hotlist_ap_found_handler handler) 527 { 528 int i, numAp, ret = 0; 529 GScanCommand *gScanCommand; 530 struct nlattr *nlData, *nlApThresholdParamList; 531 interface_info *ifaceInfo = getIfaceInfo(iface); 532 wifi_handle wifiHandle = getWifiHandle(iface); 533 534 ALOGD("Setting GScan BSSID Hotlist, halHandle = %p", wifiHandle); 535 536 /* Check if a similar request to set bssid hotlist was made earlier. 537 * Right now we don't differentiate between the case where (i) the new 538 * Request Id is different from the current one vs (ii) case where both 539 * new and Request IDs are the same. 540 */ 541 if (GScanSetBssidHotlistCmdEventHandler) 542 if (id == GScanSetBssidHotlistCmdEventHandler->get_request_id()) { 543 ALOGE("%s: GSCAN Set BSSID Hotlist for request Id %d is still" 544 "running. Exit", __func__, id); 545 return WIFI_ERROR_TOO_MANY_REQUESTS; 546 } else { 547 ALOGD("%s: GSCAN Set BSSID Hotlist for a different Request Id:%d" 548 "is requested. Not supported. Exit", __func__, id); 549 return WIFI_ERROR_NOT_SUPPORTED; 550 } 551 552 gScanCommand = 553 new GScanCommand( 554 wifiHandle, 555 id, 556 OUI_QCA, 557 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST); 558 if (gScanCommand == NULL) { 559 ALOGE("%s: Error GScanCommand NULL", __func__); 560 return WIFI_ERROR_UNKNOWN; 561 } 562 563 GScanCallbackHandler callbackHandler; 564 memset(&callbackHandler, 0, sizeof(callbackHandler)); 565 callbackHandler.set_bssid_hotlist = set_bssid_hotlist_cb, 566 567 ret = gScanCommand->setCallbackHandler(callbackHandler); 568 if (ret < 0) 569 goto cleanup; 570 571 /* Create the NL message. */ 572 ret = gScanCommand->create(); 573 if (ret < 0) 574 goto cleanup; 575 576 /* Set the interface Id of the message. */ 577 ret = gScanCommand->set_iface_id(ifaceInfo->name); 578 if (ret < 0) 579 goto cleanup; 580 581 /* Add the vendor specific attributes for the NL command. */ 582 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 583 if (!nlData) 584 goto cleanup; 585 586 numAp = (unsigned int)params.num_ap > MAX_HOTLIST_APS ? MAX_HOTLIST_APS : params.num_ap; 587 if (gScanCommand->put_u32( 588 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 589 id) || 590 gScanCommand->put_u32( 591 QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP, 592 numAp)) 593 { 594 goto cleanup; 595 } 596 597 /* Add the vendor specific attributes for the NL command. */ 598 nlApThresholdParamList = 599 gScanCommand->attr_start( 600 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM); 601 if (!nlApThresholdParamList) 602 goto cleanup; 603 604 /* Add nested NL attributes for AP Threshold Param. */ 605 for (i = 0; i < numAp; i++) { 606 ap_threshold_param apThreshold = params.ap[i]; 607 struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i); 608 if (!nlApThresholdParam) 609 goto cleanup; 610 if (gScanCommand->put_addr( 611 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID, 612 apThreshold.bssid) || 613 gScanCommand->put_s32( 614 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW, 615 apThreshold.low) || 616 gScanCommand->put_s32( 617 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH, 618 apThreshold.high) || 619 gScanCommand->put_u32( 620 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_CHANNEL, 621 apThreshold.channel)) 622 { 623 goto cleanup; 624 } 625 gScanCommand->attr_end(nlApThresholdParam); 626 } 627 628 gScanCommand->attr_end(nlApThresholdParamList); 629 630 gScanCommand->attr_end(nlData); 631 632 ret = gScanCommand->allocRspParams(eGScanSetBssidHotlistRspParams); 633 if (ret != 0) { 634 ALOGE("%s: Failed to allocate memory to the response struct. " 635 "Error:%d", __func__, ret); 636 goto cleanup; 637 } 638 639 callbackHandler.on_hotlist_ap_found = handler.on_hotlist_ap_found; 640 /* Create an object of the event handler class to take care of the 641 * asychronous events on the north-bound. 642 */ 643 GScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler( 644 wifiHandle, 645 id, 646 OUI_QCA, 647 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST, 648 callbackHandler); 649 if (GScanSetBssidHotlistCmdEventHandler == NULL) { 650 ALOGE("%s: Error instantiating GScanSetBssidHotlistCmdEventHandler.", 651 __func__); 652 ret = WIFI_ERROR_UNKNOWN; 653 goto cleanup; 654 } 655 656 ALOGD("%s: Handler object was created for HOTLIST_AP_FOUND.", __func__); 657 658 gScanCommand->waitForRsp(true); 659 ret = gScanCommand->requestEvent(); 660 if (ret != 0) { 661 ALOGE("%s: requestEvent Error:%d",__func__, ret); 662 goto cleanup; 663 } 664 665 gScanCommand->getSetBssidHotlistRspParams((u32 *)&ret); 666 if (ret != 0) 667 { 668 goto cleanup; 669 } 670 671 cleanup: 672 gScanCommand->freeRspParams(eGScanSetBssidHotlistRspParams); 673 ALOGI("%s: Delete object. ", __func__); 674 delete gScanCommand; 675 /* Delete the command event handler object if ret != 0 */ 676 if (ret && GScanSetBssidHotlistCmdEventHandler) { 677 delete GScanSetBssidHotlistCmdEventHandler; 678 GScanSetBssidHotlistCmdEventHandler = NULL; 679 } 680 return (wifi_error)ret; 681 } 682 683 void reset_bssid_hotlist_cb(int status) 684 { 685 ALOGD("%s: Status = %d.", __func__, status); 686 } 687 688 wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, 689 wifi_interface_handle iface) 690 { 691 int ret = 0; 692 GScanCommand *gScanCommand; 693 struct nlattr *nlData; 694 interface_info *ifaceInfo = getIfaceInfo(iface); 695 wifi_handle wifiHandle = getWifiHandle(iface); 696 697 ALOGE("Resetting GScan BSSID Hotlist, halHandle = %p", wifiHandle); 698 699 if (GScanSetBssidHotlistCmdEventHandler) { 700 if (id != GScanSetBssidHotlistCmdEventHandler->get_request_id()) { 701 ALOGE("%s: GSCAN Reset Hotlist BSSID requested for request Id %d" 702 "not matching that of existing GScan Set Hotlist BSSID:%d. " 703 "Exit", __func__, id, 704 GScanSetBssidHotlistCmdEventHandler->get_request_id()); 705 return WIFI_ERROR_INVALID_REQUEST_ID; 706 } 707 } 708 709 gScanCommand = new GScanCommand( 710 wifiHandle, 711 id, 712 OUI_QCA, 713 QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST); 714 715 if (gScanCommand == NULL) { 716 ALOGE("%s: Error GScanCommand NULL", __func__); 717 return WIFI_ERROR_UNKNOWN; 718 } 719 720 GScanCallbackHandler callbackHandler; 721 memset(&callbackHandler, 0, sizeof(callbackHandler)); 722 callbackHandler.reset_bssid_hotlist = reset_bssid_hotlist_cb; 723 724 ret = gScanCommand->setCallbackHandler(callbackHandler); 725 if (ret < 0) 726 goto cleanup; 727 728 /* Create the NL message. */ 729 ret = gScanCommand->create(); 730 if (ret < 0) 731 goto cleanup; 732 733 /* Set the interface Id of the message. */ 734 ret = gScanCommand->set_iface_id(ifaceInfo->name); 735 if (ret < 0) 736 goto cleanup; 737 738 /* Add the vendor specific attributes for the NL command. */ 739 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 740 if (!nlData) 741 goto cleanup; 742 743 ret = gScanCommand->put_u32( 744 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id); 745 if (ret < 0) 746 goto cleanup; 747 748 gScanCommand->attr_end(nlData); 749 750 ret = gScanCommand->allocRspParams(eGScanResetBssidHotlistRspParams); 751 if (ret != 0) { 752 ALOGE("%s: Failed to allocate memory to the response struct. " 753 "Error:%d", __func__, ret); 754 goto cleanup; 755 } 756 757 gScanCommand->waitForRsp(true); 758 ret = gScanCommand->requestEvent(); 759 if (ret != 0) { 760 ALOGE("%s: requestEvent Error:%d",__func__, ret); 761 goto cleanup; 762 } 763 764 gScanCommand->getResetBssidHotlistRspParams((u32 *)&ret); 765 if (ret != 0) 766 { 767 goto cleanup; 768 } 769 770 if (GScanSetBssidHotlistCmdEventHandler) { 771 delete GScanSetBssidHotlistCmdEventHandler; 772 GScanSetBssidHotlistCmdEventHandler = NULL; 773 } 774 775 cleanup: 776 gScanCommand->freeRspParams(eGScanResetBssidHotlistRspParams); 777 ALOGI("%s: Delete object.", __func__); 778 delete gScanCommand; 779 return (wifi_error)ret; 780 } 781 782 void set_significant_change_cb(int status) 783 { 784 ALOGD("%s: Status = %d.", __func__, status); 785 } 786 787 /* Set the GSCAN Significant AP Change list. */ 788 wifi_error wifi_set_significant_change_handler(wifi_request_id id, 789 wifi_interface_handle iface, 790 wifi_significant_change_params params, 791 wifi_significant_change_handler handler) 792 { 793 int i, numAp, ret = 0; 794 GScanCommand *gScanCommand; 795 struct nlattr *nlData, *nlApThresholdParamList; 796 interface_info *ifaceInfo = getIfaceInfo(iface); 797 wifi_handle wifiHandle = getWifiHandle(iface); 798 799 ALOGE("Setting GScan Significant Change, halHandle = %p", wifiHandle); 800 801 /* Check if a similar request to set significant change was made earlier. 802 * Right now we don't differentiate between the case where (i) the new 803 * Request Id is different from the current one vs (ii) both new and 804 * Request Ids are the same. 805 */ 806 if (GScanSetSignificantChangeCmdEventHandler) 807 if (id == GScanSetSignificantChangeCmdEventHandler->get_request_id()) { 808 ALOGE("%s: GSCAN Set Significant Change for request Id %d is still" 809 "running. Exit", __func__, id); 810 return WIFI_ERROR_TOO_MANY_REQUESTS; 811 } else { 812 ALOGE("%s: GSCAN Set Significant Change for a different Request " 813 "Id:%d is requested. Not supported. Exit", __func__, id); 814 return WIFI_ERROR_NOT_SUPPORTED; 815 } 816 817 gScanCommand = new GScanCommand( 818 wifiHandle, 819 id, 820 OUI_QCA, 821 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE); 822 if (gScanCommand == NULL) { 823 ALOGE("%s: Error GScanCommand NULL", __func__); 824 return WIFI_ERROR_UNKNOWN; 825 } 826 827 GScanCallbackHandler callbackHandler; 828 memset(&callbackHandler, 0, sizeof(callbackHandler)); 829 callbackHandler.set_significant_change = set_significant_change_cb; 830 831 ret = gScanCommand->setCallbackHandler(callbackHandler); 832 if (ret < 0) 833 goto cleanup; 834 835 /* Create the NL message. */ 836 ret = gScanCommand->create(); 837 if (ret < 0) 838 goto cleanup; 839 840 /* Set the interface Id of the message. */ 841 ret = gScanCommand->set_iface_id(ifaceInfo->name); 842 if (ret < 0) 843 goto cleanup; 844 845 /* Add the vendor specific attributes for the NL command. */ 846 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 847 if (!nlData) 848 goto cleanup; 849 850 numAp = (unsigned int)params.num_ap > MAX_SIGNIFICANT_CHANGE_APS ? 851 MAX_SIGNIFICANT_CHANGE_APS : params.num_ap; 852 853 if (gScanCommand->put_u32( 854 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 855 id) || 856 gScanCommand->put_u32( 857 QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE, 858 params.rssi_sample_size) || 859 gScanCommand->put_u32( 860 QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE, 861 params.lost_ap_sample_size) || 862 gScanCommand->put_u32( 863 QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING, 864 params.min_breaching) || 865 gScanCommand->put_u32( 866 QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP, 867 numAp)) 868 { 869 goto cleanup; 870 } 871 872 /* Add the vendor specific attributes for the NL command. */ 873 nlApThresholdParamList = 874 gScanCommand->attr_start( 875 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM); 876 if (!nlApThresholdParamList) 877 goto cleanup; 878 879 /* Add nested NL attributes for AP Threshold Param list. */ 880 for (i = 0; i < numAp; i++) { 881 ap_threshold_param apThreshold = params.ap[i]; 882 struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i); 883 if (!nlApThresholdParam) 884 goto cleanup; 885 if ( gScanCommand->put_addr( 886 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID, 887 apThreshold.bssid) || 888 gScanCommand->put_s32( 889 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW, 890 apThreshold.low) || 891 gScanCommand->put_s32( 892 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH, 893 apThreshold.high) || 894 gScanCommand->put_u32( 895 QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_CHANNEL, 896 apThreshold.channel) ) 897 { 898 goto cleanup; 899 } 900 gScanCommand->attr_end(nlApThresholdParam); 901 } 902 903 gScanCommand->attr_end(nlApThresholdParamList); 904 905 gScanCommand->attr_end(nlData); 906 907 ret = gScanCommand->allocRspParams(eGScanSetSignificantChangeRspParams); 908 if (ret != 0) { 909 ALOGE("%s: Failed to allocate memory to the response struct. " 910 "Error:%d", __func__, ret); 911 goto cleanup; 912 } 913 914 callbackHandler.on_significant_change = handler.on_significant_change; 915 /* Create an object of the event handler class to take care of the 916 * asychronous events on the north-bound. 917 */ 918 GScanSetSignificantChangeCmdEventHandler = new GScanCommandEventHandler( 919 wifiHandle, 920 id, 921 OUI_QCA, 922 QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE, 923 callbackHandler); 924 if (GScanSetSignificantChangeCmdEventHandler == NULL) { 925 ALOGE("%s: Error in instantiating, " 926 "GScanSetSignificantChangeCmdEventHandler.", 927 __func__); 928 ret = WIFI_ERROR_UNKNOWN; 929 goto cleanup; 930 } 931 932 ALOGD("%s: Event handler object was created for SIGNIFICANT_CHANGE.", 933 __func__); 934 935 gScanCommand->waitForRsp(true); 936 ret = gScanCommand->requestEvent(); 937 if (ret != 0) { 938 ALOGE("%s: requestEvent Error:%d",__func__, ret); 939 goto cleanup; 940 } 941 942 gScanCommand->getSetSignificantChangeRspParams((u32 *)&ret); 943 if (ret != 0) 944 { 945 goto cleanup; 946 } 947 948 cleanup: 949 gScanCommand->freeRspParams(eGScanSetSignificantChangeRspParams); 950 ALOGI("%s: Delete object.", __func__); 951 /* Delete the command event handler object if ret != 0 */ 952 if (ret && GScanSetSignificantChangeCmdEventHandler) { 953 delete GScanSetSignificantChangeCmdEventHandler; 954 GScanSetSignificantChangeCmdEventHandler = NULL; 955 } 956 delete gScanCommand; 957 return (wifi_error)ret; 958 } 959 960 void reset_significant_change_cb(int status) 961 { 962 ALOGD("%s: Status = %d.", __func__, status); 963 } 964 965 /* Clear the GSCAN Significant AP change list. */ 966 wifi_error wifi_reset_significant_change_handler(wifi_request_id id, 967 wifi_interface_handle iface) 968 { 969 int ret = 0; 970 GScanCommand *gScanCommand; 971 struct nlattr *nlData; 972 interface_info *ifaceInfo = getIfaceInfo(iface); 973 wifi_handle wifiHandle = getWifiHandle(iface); 974 975 ALOGD("Resetting GScan Significant Change, halHandle = %p", wifiHandle); 976 977 if (GScanSetSignificantChangeCmdEventHandler) { 978 if (id != GScanSetSignificantChangeCmdEventHandler->get_request_id()) { 979 ALOGE("%s: GSCAN Reset Significant Change requested for request " 980 "Id %d not matching that of existing GScan Set Hotlist " 981 "BSSID:%d. Exit", __func__, id, 982 GScanSetSignificantChangeCmdEventHandler->get_request_id()); 983 return WIFI_ERROR_INVALID_REQUEST_ID; 984 } 985 } 986 987 gScanCommand = 988 new GScanCommand 989 ( 990 wifiHandle, 991 id, 992 OUI_QCA, 993 QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE); 994 if (gScanCommand == NULL) { 995 ALOGE("%s: Error GScanCommand NULL", __func__); 996 return WIFI_ERROR_UNKNOWN; 997 } 998 999 GScanCallbackHandler callbackHandler; 1000 memset(&callbackHandler, 0, sizeof(callbackHandler)); 1001 callbackHandler.reset_significant_change = reset_significant_change_cb; 1002 1003 ret = gScanCommand->setCallbackHandler(callbackHandler); 1004 if (ret < 0) 1005 goto cleanup; 1006 1007 /* Create the NL message. */ 1008 ret = gScanCommand->create(); 1009 if (ret < 0) 1010 goto cleanup; 1011 1012 /* Set the interface Id of the message. */ 1013 ret = gScanCommand->set_iface_id(ifaceInfo->name); 1014 if (ret < 0) 1015 goto cleanup; 1016 1017 /* Add the vendor specific attributes for the NL command. */ 1018 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 1019 if (!nlData) 1020 goto cleanup; 1021 1022 ret = gScanCommand->put_u32( 1023 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 1024 id); 1025 if (ret < 0) 1026 goto cleanup; 1027 1028 gScanCommand->attr_end(nlData); 1029 1030 ret = gScanCommand->allocRspParams(eGScanResetSignificantChangeRspParams); 1031 if (ret != 0) { 1032 ALOGE("%s: Failed to allocate memory to the response struct. " 1033 "Error:%d", __func__, ret); 1034 goto cleanup; 1035 } 1036 1037 gScanCommand->waitForRsp(true); 1038 ret = gScanCommand->requestEvent(); 1039 if (ret != 0) { 1040 ALOGE("%s: requestEvent Error:%d",__func__, ret); 1041 goto cleanup; 1042 } 1043 1044 gScanCommand->getResetSignificantChangeRspParams((u32 *)&ret); 1045 if (ret != 0) 1046 { 1047 goto cleanup; 1048 } 1049 1050 if (GScanSetSignificantChangeCmdEventHandler) { 1051 delete GScanSetSignificantChangeCmdEventHandler; 1052 GScanSetSignificantChangeCmdEventHandler = NULL; 1053 } 1054 1055 cleanup: 1056 gScanCommand->freeRspParams(eGScanResetSignificantChangeRspParams); 1057 ALOGI("%s: Delete object.", __func__); 1058 delete gScanCommand; 1059 return (wifi_error)ret; 1060 } 1061 1062 void get_gscan_cached_results_cb(u8 moreData, u32 numResults) 1063 { 1064 ALOGD("%s: More data = %d.", __func__, moreData); 1065 ALOGD("%s: Number of cached results = %d.", __func__, numResults); 1066 } 1067 1068 /* Get the GSCAN cached scan results. */ 1069 wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, 1070 byte flush, int max, 1071 wifi_scan_result *results, 1072 int *num) 1073 { 1074 int requestId, ret = 0; 1075 wifi_scan_result *result = results; 1076 u32 j = 0; 1077 int i = 0; 1078 u8 moreData = 0; 1079 u16 waitTime = GSCAN_EVENT_WAIT_TIME_SECONDS; 1080 GScanCommand *gScanCommand; 1081 struct nlattr *nlData; 1082 1083 interface_info *ifaceInfo = getIfaceInfo(iface); 1084 wifi_handle wifiHandle = getWifiHandle(iface); 1085 1086 if (results == NULL) { 1087 ALOGE("%s: NULL results pointer provided. Exit.", 1088 __func__); 1089 return WIFI_ERROR_INVALID_ARGS; 1090 } 1091 1092 /* No request id from caller, so generate one and pass it on to the driver. */ 1093 /* Generate it randomly */ 1094 srand(time(NULL)); 1095 requestId = rand(); 1096 1097 ALOGE("Getting GScan Cached Results, halHandle = %p", wifiHandle); 1098 1099 gScanCommand = new GScanCommand( 1100 wifiHandle, 1101 requestId, 1102 OUI_QCA, 1103 QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS); 1104 if (gScanCommand == NULL) { 1105 ALOGE("%s: Error GScanCommand NULL", __func__); 1106 return WIFI_ERROR_UNKNOWN; 1107 } 1108 1109 GScanCallbackHandler callbackHandler; 1110 memset(&callbackHandler, 0, sizeof(callbackHandler)); 1111 callbackHandler.get_cached_results = get_gscan_cached_results_cb; 1112 1113 ret = gScanCommand->setCallbackHandler(callbackHandler); 1114 if (ret < 0) 1115 goto cleanup; 1116 1117 /* Create the NL message. */ 1118 ret = gScanCommand->create(); 1119 if (ret < 0) 1120 goto cleanup; 1121 1122 /* Set the interface Id of the message. */ 1123 ret = gScanCommand->set_iface_id(ifaceInfo->name); 1124 if (ret < 0) 1125 goto cleanup; 1126 1127 /* Add the vendor specific attributes for the NL command. */ 1128 nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); 1129 if (!nlData) 1130 goto cleanup; 1131 1132 if (ret < 0) 1133 goto cleanup; 1134 1135 if (gScanCommand->put_u32( 1136 QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, 1137 requestId) || 1138 gScanCommand->put_u8( 1139 QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH, 1140 flush) || 1141 gScanCommand->put_u32( 1142 QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX, 1143 max)) 1144 { 1145 goto cleanup; 1146 } 1147 gScanCommand->attr_end(nlData); 1148 ret = gScanCommand->allocRspParams(eGScanGetCachedResultsRspParams); 1149 if (ret != 0) { 1150 ALOGE("%s: Failed to allocate memory fo response struct. Error:%d", 1151 __func__, ret); 1152 goto cleanup; 1153 } 1154 1155 gScanCommand->waitForRsp(true); 1156 ret = gScanCommand->requestEvent(); 1157 if (ret != 0) { 1158 ALOGE("%s: requestEvent Error:%d",__func__, ret); 1159 goto cleanup; 1160 } 1161 1162 /* Read more data flag and number of results of retrieved cached results 1163 * from driver/firmware. 1164 * If more data is 0 or numResults >= max, return with results populated. 1165 * Otherwise, loop in 4s wait for next results fragment(s). 1166 */ 1167 ret = gScanCommand->getGetCachedResultsRspParams(max, 1168 (u8 *)&moreData, 1169 num, 1170 results); 1171 while (!ret && moreData && (*num < max)) { 1172 int res = gScanCommand->timed_wait(waitTime); 1173 if (res == ETIMEDOUT) { 1174 ALOGE("%s: Time out happened.", __func__); 1175 /*Proceed to cleanup & return whatever data avaiable at this time*/ 1176 goto cleanup; 1177 } 1178 ALOGD("%s: Command invoked return value:%d",__func__, res); 1179 /* Read the moreData and numResults again and possibly append new 1180 * cached results to the list. 1181 */ 1182 ret = gScanCommand->getGetCachedResultsRspParams(max, 1183 (u8 *)&moreData, 1184 num, 1185 results); 1186 } 1187 if (!ret) { 1188 for(i=0; i< *num; i++) 1189 { 1190 ALOGI("HAL: Result : %d\n", i+1); 1191 ALOGI("HAL: ts %lld \n", result->ts); 1192 ALOGI("HAL: SSID %s \n", result->ssid); 1193 ALOGI("HAL: BSSID: " 1194 "%02x:%02x:%02x:%02x:%02x:%02x \n", 1195 result->bssid[0], result->bssid[1], result->bssid[2], 1196 result->bssid[3], result->bssid[4], result->bssid[5]); 1197 ALOGI("HAL: channel %d \n", result->channel); 1198 ALOGI("HAL: rssi %d \n", result->rssi); 1199 ALOGI("HAL: rtt %lld \n", result->rtt); 1200 ALOGI("HAL: rtt_sd %lld \n", result->rtt_sd); 1201 ALOGI("HAL: beacon period %d \n", 1202 result->beacon_period); 1203 ALOGI("HAL: capability %d \n", result->capability); 1204 ALOGI("HAL: IE length %d \n", result->ie_length); 1205 ALOGI("HAL: IE Data \n"); 1206 hexdump(result->ie_data, result->ie_length); 1207 result = (wifi_scan_result *) 1208 ((u8 *)&results[i] + sizeof(wifi_scan_result) + 1209 result->ie_length); 1210 } 1211 } 1212 cleanup: 1213 gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams); 1214 ALOGI("%s: Delete object.", __func__); 1215 delete gScanCommand; 1216 return (wifi_error)ret; 1217 } 1218 1219 GScanCommand::GScanCommand(wifi_handle handle, int id, u32 vendor_id, 1220 u32 subcmd) 1221 : WifiVendorCommand(handle, id, vendor_id, subcmd) 1222 { 1223 ALOGD("GScanCommand %p constructed", this); 1224 /* Initialize the member data variables here */ 1225 mStartGScanRspParams = NULL; 1226 mStopGScanRspParams = NULL; 1227 mSetBssidHotlistRspParams = NULL; 1228 mResetBssidHotlistRspParams = NULL; 1229 mSetSignificantChangeRspParams = NULL; 1230 mResetSignificantChangeRspParams = NULL; 1231 mGetCapabilitiesRspParams = NULL; 1232 mGetCachedResultsRspParams = NULL; 1233 mGetCachedResultsNumResults = 0; 1234 mChannels = NULL; 1235 mMaxChannels = 0; 1236 mNumChannelsPtr = NULL; 1237 mWaitforRsp = false; 1238 1239 mRequestId = id; 1240 memset(&mHandler, 0,sizeof(mHandler)); 1241 } 1242 1243 GScanCommand::~GScanCommand() 1244 { 1245 ALOGD("GScanCommand %p destructor", this); 1246 unregisterVendorHandler(mVendor_id, mSubcmd); 1247 } 1248 1249 1250 /* This function implements creation of Vendor command */ 1251 int GScanCommand::create() { 1252 int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); 1253 if (ret < 0) { 1254 return ret; 1255 } 1256 1257 /* Insert the oui in the msg */ 1258 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); 1259 if (ret < 0) 1260 goto out; 1261 /* Insert the subcmd in the msg */ 1262 ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); 1263 if (ret < 0) 1264 goto out; 1265 1266 ALOGI("%s: mVendor_id = %d, Subcmd = %d.", 1267 __func__, mVendor_id, mSubcmd); 1268 1269 out: 1270 return ret; 1271 } 1272 1273 /* Callback handlers registered for nl message send */ 1274 static int error_handler_gscan(struct sockaddr_nl *nla, struct nlmsgerr *err, 1275 void *arg) 1276 { 1277 struct sockaddr_nl *tmp; 1278 int *ret = (int *)arg; 1279 tmp = nla; 1280 *ret = err->error; 1281 ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret))); 1282 return NL_STOP; 1283 } 1284 1285 /* Callback handlers registered for nl message send */ 1286 static int ack_handler_gscan(struct nl_msg *msg, void *arg) 1287 { 1288 int *ret = (int *)arg; 1289 struct nl_msg * a; 1290 1291 ALOGE("%s: called", __func__); 1292 a = msg; 1293 *ret = 0; 1294 return NL_STOP; 1295 } 1296 1297 /* Callback handlers registered for nl message send */ 1298 static int finish_handler_gscan(struct nl_msg *msg, void *arg) 1299 { 1300 int *ret = (int *)arg; 1301 struct nl_msg * a; 1302 1303 ALOGE("%s: called", __func__); 1304 a = msg; 1305 *ret = 0; 1306 return NL_SKIP; 1307 } 1308 1309 /* 1310 * Override base class requestEvent and implement little differently here. 1311 * This will send the request message. 1312 * We don't wait for any response back in case of gscan as it is asynchronous, 1313 * thus no wait for condition. 1314 */ 1315 int GScanCommand::requestEvent() 1316 { 1317 int res = -1; 1318 struct nl_cb *cb; 1319 1320 ALOGD("%s: Entry.", __func__); 1321 1322 cb = nl_cb_alloc(NL_CB_DEFAULT); 1323 if (!cb) { 1324 ALOGE("%s: Callback allocation failed",__func__); 1325 res = -1; 1326 goto out; 1327 } 1328 1329 /* Send message */ 1330 ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock); 1331 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); 1332 if (res < 0) 1333 goto out; 1334 res = 1; 1335 1336 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_gscan, &res); 1337 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_gscan, &res); 1338 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_gscan, &res); 1339 1340 /* Err is populated as part of finish_handler. */ 1341 while (res > 0){ 1342 nl_recvmsgs(mInfo->cmd_sock, cb); 1343 } 1344 1345 ALOGD("%s: Msg sent, res=%d, mWaitForRsp=%d", __func__, res, mWaitforRsp); 1346 /* Only wait for the asynchronous event if HDD returns success, res=0 */ 1347 if (!res && (mWaitforRsp == true)) { 1348 struct timespec abstime; 1349 abstime.tv_sec = 4; 1350 abstime.tv_nsec = 0; 1351 res = mCondition.wait(abstime); 1352 if (res == ETIMEDOUT) 1353 { 1354 ALOGE("%s: Time out happened.", __func__); 1355 } 1356 ALOGD("%s: Command invoked return value:%d, mWaitForRsp=%d", 1357 __func__, res, mWaitforRsp); 1358 } 1359 out: 1360 /* Free the VendorData */ 1361 if (mVendorData) { 1362 free(mVendorData); 1363 } 1364 mVendorData = NULL; 1365 /* Cleanup the mMsg */ 1366 mMsg.destroy(); 1367 return res; 1368 } 1369 1370 int GScanCommand::requestResponse() 1371 { 1372 ALOGD("%s: request a response", __func__); 1373 return WifiCommand::requestResponse(mMsg); 1374 } 1375 1376 int GScanCommand::handleResponse(WifiEvent &reply) { 1377 ALOGI("Received a GScan response message from Driver"); 1378 u32 status; 1379 int i = 0; 1380 WifiVendorCommand::handleResponse(reply); 1381 1382 switch(mSubcmd) 1383 { 1384 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS: 1385 { 1386 struct nlattr *tb_vendor[ 1387 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 1388 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 1389 (struct nlattr *)mVendorData,mDataLen, NULL); 1390 1391 if (tb_vendor[ 1392 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]) { 1393 u32 val; 1394 val = nla_get_u32( 1395 tb_vendor[ 1396 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]); 1397 1398 ALOGD("%s: Num channels : %d", __func__, val); 1399 val = val > (unsigned int)mMaxChannels ? 1400 (unsigned int)mMaxChannels : val; 1401 *mNumChannelsPtr = val; 1402 1403 /* Extract the list of channels. */ 1404 if (*mNumChannelsPtr > 0 && 1405 tb_vendor[ 1406 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS]) { 1407 nla_memcpy(mChannels, 1408 tb_vendor[ 1409 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS], 1410 sizeof(wifi_channel) * (*mNumChannelsPtr)); 1411 } 1412 1413 ALOGD("%s: Get valid channels response received.", 1414 __func__); 1415 ALOGD("%s: Num channels : %d", 1416 __func__, *mNumChannelsPtr); 1417 ALOGD("%s: List of valid channels is: ", __func__); 1418 for(i = 0; i < *mNumChannelsPtr; i++) 1419 { 1420 ALOGD("%u", *(mChannels + i)); 1421 } 1422 } 1423 } 1424 break; 1425 default : 1426 ALOGE("%s: Wrong GScan subcmd response received %d", 1427 __func__, mSubcmd); 1428 } 1429 return NL_SKIP; 1430 } 1431 1432 /* Called to parse and extract cached results. */ 1433 static int gscan_get_cached_results(u32 num_results, 1434 wifi_scan_result *results, 1435 u32 starting_index, 1436 struct nlattr **tb_vendor) 1437 { 1438 u32 i = starting_index; 1439 struct nlattr *scanResultsInfo; 1440 int rem = 0; 1441 u32 len = 0; 1442 ALOGE("starting counter: %d", i); 1443 1444 for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ 1445 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), 1446 rem = nla_len(tb_vendor[ 1447 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST 1448 ]); 1449 nla_ok(scanResultsInfo, rem); 1450 scanResultsInfo = nla_next(scanResultsInfo, &(rem))) 1451 { 1452 struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 1453 nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 1454 (struct nlattr *) nla_data(scanResultsInfo), 1455 nla_len(scanResultsInfo), NULL); 1456 1457 if (! 1458 tb2[ 1459 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP 1460 ]) 1461 { 1462 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_TIME_STAMP" 1463 " not found"); 1464 return WIFI_ERROR_INVALID_ARGS; 1465 } 1466 results[i].ts = 1467 nla_get_u64( 1468 tb2[ 1469 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP 1470 ]); 1471 if (! 1472 tb2[ 1473 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID 1474 ]) 1475 { 1476 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_SSID " 1477 "not found"); 1478 return WIFI_ERROR_INVALID_ARGS; 1479 } 1480 len = nla_len(tb2[ 1481 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); 1482 len = 1483 sizeof(results->ssid) <= len ? sizeof(results->ssid) : len; 1484 memcpy((void *)&results[i].ssid, 1485 nla_data( 1486 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); 1487 if (! 1488 tb2[ 1489 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID 1490 ]) 1491 { 1492 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_BSSID " 1493 "not found"); 1494 return WIFI_ERROR_INVALID_ARGS; 1495 } 1496 len = nla_len( 1497 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); 1498 len = 1499 sizeof(results->bssid) <= len ? sizeof(results->bssid) : len; 1500 memcpy(&results[i].bssid, 1501 nla_data( 1502 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); 1503 if (! 1504 tb2[ 1505 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL 1506 ]) 1507 { 1508 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_CHANNEL " 1509 "not found"); 1510 return WIFI_ERROR_INVALID_ARGS; 1511 } 1512 results[i].channel = 1513 nla_get_u32( 1514 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); 1515 if (! 1516 tb2[ 1517 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI 1518 ]) 1519 { 1520 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_RSSI " 1521 "not found"); 1522 return WIFI_ERROR_INVALID_ARGS; 1523 } 1524 results[i].rssi = 1525 nla_get_u32( 1526 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); 1527 if (! 1528 tb2[ 1529 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT 1530 ]) 1531 { 1532 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_RTT " 1533 "not found"); 1534 return WIFI_ERROR_INVALID_ARGS; 1535 } 1536 results[i].rtt = 1537 nla_get_u32( 1538 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); 1539 if (! 1540 tb2[ 1541 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD 1542 ]) 1543 { 1544 ALOGE("gscan_get_cached_results: RESULTS_SCAN_RESULT_RTT_SD " 1545 "not found"); 1546 return WIFI_ERROR_INVALID_ARGS; 1547 } 1548 results[i].rtt_sd = 1549 nla_get_u32( 1550 tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); 1551 1552 ALOGE("gscan_get_cached_results: ts %lld ", results[i].ts); 1553 ALOGE("gscan_get_cached_results: SSID %s ", results[i].ssid); 1554 ALOGE("gscan_get_cached_results: " 1555 "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n", 1556 results[i].bssid[0], results[i].bssid[1], results[i].bssid[2], 1557 results[i].bssid[3], results[i].bssid[4], results[i].bssid[5]); 1558 ALOGE("gscan_get_cached_results: channel %d ", results[i].channel); 1559 ALOGE("gscan_get_cached_results: rssi %d ", results[i].rssi); 1560 ALOGE("gscan_get_cached_results: rtt %lld ", results[i].rtt); 1561 ALOGE("gscan_get_cached_results: rtt_sd %lld ", results[i].rtt_sd); 1562 /* Increment loop index for next record */ 1563 i++; 1564 } 1565 ALOGE("%s: Exited the for loop", __func__); 1566 return WIFI_SUCCESS; 1567 } 1568 1569 /* This function will be the main handler for incoming (from driver) GSscan_SUBCMD. 1570 * Calls the appropriate callback handler after parsing the vendor data. 1571 */ 1572 int GScanCommand::handleEvent(WifiEvent &event) 1573 { 1574 ALOGI("Got a GSCAN Event message from the Driver."); 1575 unsigned i = 0; 1576 u32 status; 1577 int ret = WIFI_SUCCESS; 1578 WifiVendorCommand::handleEvent(event); 1579 1580 struct nlattr *tbVendor[ 1581 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; 1582 nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, 1583 (struct nlattr *)mVendorData, 1584 mDataLen, NULL); 1585 1586 switch(mSubcmd) 1587 { 1588 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START: 1589 { 1590 if (mStartGScanRspParams){ 1591 mStartGScanRspParams->status = 1592 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1593 if (mHandler.start) 1594 (*mHandler.start)(mStartGScanRspParams->status); 1595 } 1596 waitForRsp(false); 1597 } 1598 break; 1599 1600 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP: 1601 { 1602 if (mStopGScanRspParams){ 1603 mStopGScanRspParams->status = 1604 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1605 if (mHandler.stop) 1606 (*mHandler.stop)(mStopGScanRspParams->status); 1607 } 1608 waitForRsp(false); 1609 } 1610 break; 1611 1612 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST: 1613 { 1614 if (mSetBssidHotlistRspParams){ 1615 mSetBssidHotlistRspParams->status = 1616 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1617 if (mHandler.set_bssid_hotlist) 1618 (*mHandler.set_bssid_hotlist) 1619 (mSetBssidHotlistRspParams->status); 1620 } 1621 waitForRsp(false); 1622 } 1623 break; 1624 1625 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST: 1626 { 1627 if (mResetBssidHotlistRspParams){ 1628 mResetBssidHotlistRspParams->status = 1629 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1630 if (mHandler.reset_bssid_hotlist) 1631 (*mHandler.reset_bssid_hotlist) 1632 (mResetBssidHotlistRspParams->status); 1633 } 1634 waitForRsp(false); 1635 } 1636 break; 1637 1638 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE: 1639 { 1640 if (mSetSignificantChangeRspParams){ 1641 mSetSignificantChangeRspParams->status = 1642 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1643 if (mHandler.set_significant_change) 1644 (*mHandler.set_significant_change) 1645 (mSetSignificantChangeRspParams->status); 1646 } 1647 waitForRsp(false); 1648 } 1649 break; 1650 1651 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE: 1652 { 1653 if (mResetSignificantChangeRspParams){ 1654 mResetSignificantChangeRspParams->status = 1655 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1656 if (mHandler.reset_significant_change) 1657 (*mHandler.reset_significant_change) 1658 (mResetSignificantChangeRspParams->status); 1659 } 1660 waitForRsp(false); 1661 } 1662 break; 1663 1664 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES: 1665 { 1666 if (!mGetCapabilitiesRspParams){ 1667 ALOGE("%s: mGetCapabilitiesRspParams ptr is NULL. Exit. ", 1668 __func__); 1669 break; 1670 } 1671 1672 if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]) { 1673 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS " 1674 "not found", __func__); 1675 ret = WIFI_ERROR_INVALID_ARGS; 1676 break; 1677 } 1678 mGetCapabilitiesRspParams->status = 1679 nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS]); 1680 1681 if (!tbVendor[ 1682 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE 1683 ]) { 1684 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_" 1685 "CAPABILITIES_MAX_SCAN_CACHE_SIZE not found", __func__); 1686 ret = WIFI_ERROR_INVALID_ARGS; 1687 break; 1688 } 1689 mGetCapabilitiesRspParams->capabilities.max_scan_cache_size = 1690 nla_get_u32(tbVendor[ 1691 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]); 1692 1693 if (!tbVendor[ 1694 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS 1695 ]) { 1696 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX" 1697 "_SCAN_BUCKETS not found", __func__); 1698 ret = WIFI_ERROR_INVALID_ARGS; 1699 break; 1700 } 1701 mGetCapabilitiesRspParams->capabilities.max_scan_buckets = 1702 nla_get_u32(tbVendor[ 1703 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS] 1704 ); 1705 1706 if (!tbVendor[ 1707 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN 1708 ]) { 1709 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX" 1710 "_AP_CACHE_PER_SCAN not found", __func__); 1711 ret = WIFI_ERROR_INVALID_ARGS; 1712 break; 1713 } 1714 mGetCapabilitiesRspParams->capabilities.max_ap_cache_per_scan = 1715 nla_get_u32(tbVendor[ 1716 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]); 1717 1718 if (!tbVendor[ 1719 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE 1720 ]) { 1721 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX" 1722 "_RSSI_SAMPLE_SIZE not found", __func__); 1723 ret = WIFI_ERROR_INVALID_ARGS; 1724 break; 1725 } 1726 mGetCapabilitiesRspParams->capabilities.max_rssi_sample_size = 1727 nla_get_u32(tbVendor[ 1728 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]); 1729 1730 if (!tbVendor[ 1731 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD 1732 ]) { 1733 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_" 1734 "MAX_SCAN_REPORTING_THRESHOLD not found", __func__); 1735 ret = WIFI_ERROR_INVALID_ARGS; 1736 break; 1737 } 1738 mGetCapabilitiesRspParams->capabilities.max_scan_reporting_threshold = 1739 nla_get_u32(tbVendor[ 1740 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD 1741 ]); 1742 1743 if (!tbVendor[ 1744 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS 1745 ]) { 1746 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_" 1747 "MAX_HOTLIST_APS not found", __func__); 1748 ret = WIFI_ERROR_INVALID_ARGS; 1749 break; 1750 } 1751 mGetCapabilitiesRspParams->capabilities.max_hotlist_aps = 1752 nla_get_u32(tbVendor[ 1753 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS]); 1754 1755 if (!tbVendor[ 1756 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS 1757 ]) { 1758 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX" 1759 "_SIGNIFICANT_WIFI_CHANGE_APS not found", __func__); 1760 ret = WIFI_ERROR_INVALID_ARGS; 1761 break; 1762 } 1763 mGetCapabilitiesRspParams->capabilities.max_significant_wifi_change_aps = 1764 nla_get_u32(tbVendor[ 1765 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]); 1766 1767 if (!tbVendor[ 1768 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES 1769 ]) { 1770 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX" 1771 "_BSSID_HISTORY_ENTRIES not found", __func__); 1772 ret = WIFI_ERROR_INVALID_ARGS; 1773 break; 1774 } 1775 mGetCapabilitiesRspParams->capabilities.max_bssid_history_entries = 1776 nla_get_u32(tbVendor[ 1777 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES 1778 ]); 1779 /* Call the call back handler func. */ 1780 if (mHandler.get_capabilities) 1781 (*mHandler.get_capabilities) 1782 (mGetCapabilitiesRspParams->status, 1783 mGetCapabilitiesRspParams->capabilities); 1784 waitForRsp(false); 1785 } 1786 break; 1787 1788 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS: 1789 { 1790 wifi_request_id id; 1791 u32 resultsBufSize = 0; 1792 u32 numResults = 0; 1793 u32 startingIndex, sizeOfObtainedScanResults; 1794 1795 if (!tbVendor[ 1796 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) { 1797 ALOGE("%s: GSCAN_RESULTS_REQUEST_ID not" 1798 "found", __func__); 1799 break; 1800 } 1801 id = nla_get_u32( 1802 tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] 1803 ); 1804 ALOGE("%s: Event has Req. ID:%d, ours:%d", 1805 __func__, id, mRequestId); 1806 /* If this is not for us, just ignore it. */ 1807 if (id != mRequestId) { 1808 ALOGE("%s: Event has Req. ID:%d <> ours:%d", 1809 __func__, id, mRequestId); 1810 break; 1811 } 1812 if (!tbVendor[ 1813 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { 1814 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not" 1815 "found", __func__); 1816 break; 1817 } 1818 numResults = nla_get_u32(tbVendor[ 1819 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); 1820 ALOGE("%s: number of results:%d", __func__, 1821 numResults); 1822 1823 if (!mGetCachedResultsRspParams) { 1824 ALOGE("%s: mGetCachedResultsRspParams is NULL, exit.", 1825 __func__); 1826 break; 1827 } 1828 1829 /* Get the memory size of previous fragments, if any. */ 1830 sizeOfObtainedScanResults = mGetCachedResultsNumResults * 1831 sizeof(wifi_scan_result); 1832 1833 mGetCachedResultsNumResults += numResults; 1834 resultsBufSize += mGetCachedResultsNumResults * 1835 sizeof(wifi_scan_result); 1836 /* Check if this chunck of cached scan results is a continuation of 1837 * a previous one, i.e., a new results fragment. 1838 */ 1839 if (mGetCachedResultsRspParams->more_data) { 1840 mGetCachedResultsRspParams->results = (wifi_scan_result *) 1841 realloc (mGetCachedResultsRspParams->results, 1842 resultsBufSize); 1843 } else { 1844 mGetCachedResultsRspParams->results = (wifi_scan_result *) 1845 malloc (resultsBufSize); 1846 } 1847 1848 ALOGE("%s: Total num of cached results received: %d. \n", 1849 __func__, mGetCachedResultsNumResults); 1850 1851 if (!mGetCachedResultsRspParams->results) { 1852 ALOGE("%s: Failed to alloc memory for results array. Exit.\n", 1853 __func__); 1854 ret = WIFI_ERROR_OUT_OF_MEMORY; 1855 break; 1856 } 1857 1858 ALOGD("(u8 *)mGetCachedResultsRspParams->results : %p " 1859 "resultsBufSize :%d oldSizeResults : %d . \n", 1860 (u8 *)mGetCachedResultsRspParams->results, 1861 resultsBufSize, sizeOfObtainedScanResults); 1862 /* Initialize the newly allocated memory area with 0. */ 1863 memset((u8 *)mGetCachedResultsRspParams->results + 1864 sizeOfObtainedScanResults, 1865 0, 1866 resultsBufSize - sizeOfObtainedScanResults); 1867 1868 /* To support fragmentation from firmware, monitor the 1869 * MORE_DTATA flag and cache results until MORE_DATA = 0. 1870 */ 1871 if (!tbVendor[ 1872 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { 1873 ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA " 1874 "not found", __func__); 1875 ret = WIFI_ERROR_INVALID_ARGS; 1876 break; 1877 } else { 1878 mGetCachedResultsRspParams->more_data = nla_get_u8( 1879 tbVendor[ 1880 QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); 1881 ALOGE("%s: More data = %d. \n", __func__, 1882 mGetCachedResultsRspParams->more_data); 1883 } 1884 1885 mGetCachedResultsRspParams->num_results = 1886 mGetCachedResultsNumResults; 1887 if (numResults) { 1888 ALOGD("%s: Extract cached results received.\n", __func__); 1889 startingIndex = 1890 mGetCachedResultsNumResults - numResults; 1891 ALOGD("%s: starting_index:%d", 1892 __func__, startingIndex); 1893 ret = gscan_get_cached_results(numResults, 1894 mGetCachedResultsRspParams->results, 1895 startingIndex, 1896 tbVendor); 1897 /* If a parsing error occurred, exit and proceed for cleanup. */ 1898 if (ret) 1899 break; 1900 } 1901 /* Send the results if no more result data fragments are expected. */ 1902 if (mHandler.get_cached_results) { 1903 (*mHandler.get_cached_results) 1904 (mGetCachedResultsRspParams->more_data, 1905 mGetCachedResultsRspParams->num_results); 1906 } 1907 waitForRsp(false); 1908 } 1909 break; 1910 1911 default: 1912 /* Error case should not happen print log */ 1913 ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd); 1914 } 1915 1916 /* A parsing error occurred, do the cleanup of gscan result lists. */ 1917 if (ret) { 1918 switch(mSubcmd) 1919 { 1920 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS: 1921 { 1922 freeRspParams(eGScanGetCachedResultsRspParams); 1923 } 1924 break; 1925 1926 case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES: 1927 break; 1928 1929 default: 1930 ALOGE("%s: Wrong GScan subcmd received %d", __func__, mSubcmd); 1931 } 1932 } 1933 1934 return NL_SKIP; 1935 } 1936 1937 int GScanCommand::setCallbackHandler(GScanCallbackHandler nHandler) 1938 { 1939 int res = 0; 1940 mHandler = nHandler; 1941 res = registerVendorHandler(mVendor_id, mSubcmd); 1942 if (res != 0) { 1943 /* Error case: should not happen, so print a log when it does. */ 1944 ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", 1945 __func__, mVendor_id, mSubcmd); 1946 } 1947 return res; 1948 } 1949 1950 /* 1951 * Allocates memory for the subCmd response struct and initializes status = -1 1952 */ 1953 int GScanCommand::allocRspParams(eGScanRspRarams cmd) 1954 { 1955 int ret = 0; 1956 switch(cmd) 1957 { 1958 case eGScanStartRspParams: 1959 mStartGScanRspParams = (GScanStartRspParams *) 1960 malloc(sizeof(GScanStartRspParams)); 1961 if (!mStartGScanRspParams) 1962 ret = -1; 1963 else 1964 mStartGScanRspParams->status = -1; 1965 break; 1966 case eGScanStopRspParams: 1967 mStopGScanRspParams = (GScanStopRspParams *) 1968 malloc(sizeof(GScanStopRspParams)); 1969 if (!mStopGScanRspParams) 1970 ret = -1; 1971 else 1972 mStopGScanRspParams->status = -1; 1973 break; 1974 case eGScanSetBssidHotlistRspParams: 1975 mSetBssidHotlistRspParams = (GScanSetBssidHotlistRspParams *) 1976 malloc(sizeof(GScanSetBssidHotlistRspParams)); 1977 if (!mSetBssidHotlistRspParams) 1978 ret = -1; 1979 else 1980 mSetBssidHotlistRspParams->status = -1; 1981 break; 1982 case eGScanResetBssidHotlistRspParams: 1983 mResetBssidHotlistRspParams = (GScanResetBssidHotlistRspParams *) 1984 malloc(sizeof(GScanResetBssidHotlistRspParams)); 1985 if (!mResetBssidHotlistRspParams) 1986 ret = -1; 1987 else 1988 mResetBssidHotlistRspParams->status = -1; 1989 break; 1990 case eGScanSetSignificantChangeRspParams: 1991 mSetSignificantChangeRspParams = 1992 (GScanSetSignificantChangeRspParams *) 1993 malloc(sizeof(GScanSetSignificantChangeRspParams)); 1994 if (!mSetSignificantChangeRspParams) 1995 ret = -1; 1996 else 1997 mSetSignificantChangeRspParams->status = -1; 1998 break; 1999 case eGScanResetSignificantChangeRspParams: 2000 mResetSignificantChangeRspParams = 2001 (GScanResetSignificantChangeRspParams *) 2002 malloc(sizeof(GScanResetSignificantChangeRspParams)); 2003 if (!mResetSignificantChangeRspParams) 2004 ret = -1; 2005 else 2006 mResetSignificantChangeRspParams->status = -1; 2007 break; 2008 case eGScanGetCapabilitiesRspParams: 2009 mGetCapabilitiesRspParams = (GScanGetCapabilitiesRspParams *) 2010 malloc(sizeof(GScanGetCapabilitiesRspParams)); 2011 if (!mGetCapabilitiesRspParams) 2012 ret = -1; 2013 else { 2014 memset(&mGetCapabilitiesRspParams->capabilities, 0, 2015 sizeof(wifi_gscan_capabilities)); 2016 mGetCapabilitiesRspParams->status = -1; 2017 } 2018 break; 2019 case eGScanGetCachedResultsRspParams: 2020 mGetCachedResultsRspParams = (GScanGetCachedResultsRspParams *) 2021 malloc(sizeof(GScanGetCachedResultsRspParams)); 2022 if (!mGetCachedResultsRspParams) 2023 ret = -1; 2024 else { 2025 mGetCachedResultsRspParams->num_results = 0; 2026 mGetCachedResultsRspParams->more_data = false; 2027 mGetCachedResultsRspParams->results = NULL; 2028 } 2029 break; 2030 default: 2031 ALOGD("%s: Wrong request for alloc.", __func__); 2032 ret = -1; 2033 } 2034 return ret; 2035 } 2036 2037 void GScanCommand::freeRspParams(eGScanRspRarams cmd) 2038 { 2039 switch(cmd) 2040 { 2041 case eGScanStartRspParams: 2042 if (mStartGScanRspParams) { 2043 free(mStartGScanRspParams); 2044 mStartGScanRspParams = NULL; 2045 } 2046 break; 2047 case eGScanStopRspParams: 2048 if (mStopGScanRspParams) { 2049 free(mStopGScanRspParams); 2050 mStopGScanRspParams = NULL; 2051 } 2052 break; 2053 case eGScanSetBssidHotlistRspParams: 2054 if (mSetBssidHotlistRspParams) { 2055 free(mSetBssidHotlistRspParams); 2056 mSetBssidHotlistRspParams = NULL; 2057 } 2058 break; 2059 case eGScanResetBssidHotlistRspParams: 2060 if (mResetBssidHotlistRspParams) { 2061 free(mResetBssidHotlistRspParams); 2062 mResetBssidHotlistRspParams = NULL; 2063 } 2064 break; 2065 case eGScanSetSignificantChangeRspParams: 2066 if (mSetSignificantChangeRspParams) { 2067 free(mSetSignificantChangeRspParams); 2068 mSetSignificantChangeRspParams = NULL; 2069 } 2070 break; 2071 case eGScanResetSignificantChangeRspParams: 2072 if (mResetSignificantChangeRspParams) { 2073 free(mResetSignificantChangeRspParams); 2074 mResetSignificantChangeRspParams = NULL; 2075 } 2076 break; 2077 case eGScanGetCapabilitiesRspParams: 2078 if (mGetCapabilitiesRspParams) { 2079 free(mGetCapabilitiesRspParams); 2080 mGetCapabilitiesRspParams = NULL; 2081 } 2082 break; 2083 case eGScanGetCachedResultsRspParams: 2084 if (mGetCachedResultsRspParams) { 2085 if (mGetCachedResultsRspParams->results) { 2086 free(mGetCachedResultsRspParams->results); 2087 mGetCachedResultsRspParams->results = NULL; 2088 } 2089 free(mGetCachedResultsRspParams); 2090 mGetCachedResultsRspParams = NULL; 2091 } 2092 break; 2093 2094 default: 2095 ALOGD("%s: Wrong request for free.", __func__); 2096 } 2097 } 2098 2099 wifi_error GScanCommand::getGetCachedResultsRspParams( 2100 int max, 2101 u8 *moreData, 2102 int *numResults, 2103 wifi_scan_result *results) 2104 { 2105 wifi_error ret = WIFI_SUCCESS; 2106 2107 if (mGetCachedResultsRspParams && results) 2108 { 2109 *moreData = mGetCachedResultsRspParams->more_data; 2110 *numResults = mGetCachedResultsRspParams->num_results > (unsigned int)max ? 2111 max : mGetCachedResultsRspParams->num_results; 2112 memcpy(results, 2113 mGetCachedResultsRspParams->results, 2114 *numResults * sizeof(wifi_scan_result)); 2115 } else { 2116 ALOGD("%s: mGetCachedResultsRspParams is NULL", __func__); 2117 ret = WIFI_ERROR_INVALID_ARGS; 2118 } 2119 return ret; 2120 } 2121 2122 void GScanCommand::getGetCapabilitiesRspParams( 2123 wifi_gscan_capabilities *capabilities, 2124 u32 *status) 2125 { 2126 if (mGetCapabilitiesRspParams && capabilities) 2127 { 2128 *status = mGetCapabilitiesRspParams->status; 2129 memcpy(capabilities, 2130 &mGetCapabilitiesRspParams->capabilities, 2131 sizeof(wifi_gscan_capabilities)); 2132 } else { 2133 ALOGD("%s: mGetCapabilitiesRspParams is NULL", __func__); 2134 } 2135 } 2136 2137 void GScanCommand::getStartGScanRspParams(u32 *status) 2138 { 2139 if (mStartGScanRspParams) 2140 { 2141 *status = mStartGScanRspParams->status; 2142 } else { 2143 ALOGD("%s: mStartGScanRspParams is NULL", __func__); 2144 } 2145 } 2146 2147 void GScanCommand::getStopGScanRspParams(u32 *status) 2148 { 2149 if (mStopGScanRspParams) 2150 { 2151 *status = mStopGScanRspParams->status; 2152 } else { 2153 ALOGD("%s: mStopGScanRspParams is NULL", __func__); 2154 } 2155 } 2156 2157 void GScanCommand::getSetBssidHotlistRspParams(u32 *status) 2158 { 2159 if (mSetBssidHotlistRspParams) 2160 { 2161 *status = mSetBssidHotlistRspParams->status; 2162 } else { 2163 ALOGD("%s: mSetBssidHotlistRspParams is NULL", __func__); 2164 } 2165 } 2166 2167 void GScanCommand::getResetBssidHotlistRspParams(u32 *status) 2168 { 2169 if (mResetBssidHotlistRspParams) 2170 { 2171 *status = mResetBssidHotlistRspParams->status; 2172 } else { 2173 ALOGD("%s: mResetBssidHotlistRspParams is NULL", __func__); 2174 } 2175 } 2176 2177 void GScanCommand::getSetSignificantChangeRspParams(u32 *status) 2178 { 2179 if (mSetSignificantChangeRspParams) 2180 { 2181 *status = mSetSignificantChangeRspParams->status; 2182 } else { 2183 ALOGD("%s: mSetSignificantChangeRspParams is NULL", __func__); 2184 } 2185 } 2186 2187 void GScanCommand::getResetSignificantChangeRspParams(u32 *status) 2188 { 2189 if (mResetSignificantChangeRspParams) 2190 { 2191 *status = mResetSignificantChangeRspParams->status; 2192 } else { 2193 ALOGD("%s: mResetSignificantChangeRspParams is NULL", __func__); 2194 } 2195 } 2196 2197 int GScanCommand::timed_wait(u16 wait_time) 2198 { 2199 struct timespec absTime; 2200 int res; 2201 absTime.tv_sec = wait_time; 2202 absTime.tv_nsec = 0; 2203 return mCondition.wait(absTime); 2204 } 2205 2206 void GScanCommand::waitForRsp(bool wait) 2207 { 2208 mWaitforRsp = wait; 2209 } 2210 2211 void GScanCommand::setMaxChannels(int max_channels) { 2212 mMaxChannels = max_channels; 2213 } 2214 2215 void GScanCommand::setChannels(int *channels) { 2216 mChannels = channels; 2217 } 2218 2219 void GScanCommand::setNumChannelsPtr(int *num_channels) { 2220 mNumChannelsPtr = num_channels; 2221 } 2222 2223