1 2 #include <stdint.h> 3 #include <fcntl.h> 4 #include <sys/socket.h> 5 #include <netlink/genl/genl.h> 6 #include <netlink/genl/family.h> 7 #include <netlink/genl/ctrl.h> 8 #include <linux/rtnetlink.h> 9 #include <netpacket/packet.h> 10 #include <linux/filter.h> 11 #include <linux/errqueue.h> 12 13 #include <linux/pkt_sched.h> 14 #include <netlink/object-api.h> 15 #include <netlink/netlink.h> 16 #include <netlink/socket.h> 17 #include <netlink/handlers.h> 18 19 #include "sync.h" 20 21 #define LOG_TAG "WifiHAL" 22 //#define LOG_NDEBUG 0 //uncomment to enable verbose logging 23 24 #include <utils/Log.h> 25 26 #include "wifi_hal.h" 27 #include "common.h" 28 #include "cpp_bindings.h" 29 30 typedef enum { 31 32 GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, 33 GSCAN_ATTRIBUTE_BASE_PERIOD, 34 GSCAN_ATTRIBUTE_BUCKETS_BAND, 35 GSCAN_ATTRIBUTE_BUCKET_ID, 36 GSCAN_ATTRIBUTE_BUCKET_PERIOD, 37 GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, 38 GSCAN_ATTRIBUTE_BUCKET_CHANNELS, 39 GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, 40 GSCAN_ATTRIBUTE_REPORT_THRESHOLD, 41 GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, 42 GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, 43 44 GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, 45 GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ 46 GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ 47 GSCAN_ENABLE_FULL_SCAN_RESULTS, 48 GSCAN_ATTRIBUTE_REPORT_EVENTS, 49 50 /* remaining reserved for additional attributes */ 51 GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, 52 GSCAN_ATTRIBUTE_FLUSH_RESULTS, 53 GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ 54 GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ 55 GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ 56 GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ 57 GSCAN_ATTRIBUTE_NUM_CHANNELS, 58 GSCAN_ATTRIBUTE_CHANNEL_LIST, 59 GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK, 60 /* remaining reserved for additional attributes */ 61 62 GSCAN_ATTRIBUTE_SSID = 40, 63 GSCAN_ATTRIBUTE_BSSID, 64 GSCAN_ATTRIBUTE_CHANNEL, 65 GSCAN_ATTRIBUTE_RSSI, 66 GSCAN_ATTRIBUTE_TIMESTAMP, 67 GSCAN_ATTRIBUTE_RTT, 68 GSCAN_ATTRIBUTE_RTTSD, 69 70 /* remaining reserved for additional attributes */ 71 72 GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, 73 GSCAN_ATTRIBUTE_RSSI_LOW, 74 GSCAN_ATTRIBUTE_RSSI_HIGH, 75 GSCAN_ATTRIBUTE_HOTLIST_ELEM, 76 GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 77 GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT, 78 79 /* remaining reserved for additional attributes */ 80 GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, 81 GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, 82 GSCAN_ATTRIBUTE_MIN_BREACHING, 83 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, 84 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 85 86 /* EPNO */ 87 GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70, 88 GSCAN_ATTRIBUTE_EPNO_SSID, 89 GSCAN_ATTRIBUTE_EPNO_SSID_LEN, 90 GSCAN_ATTRIBUTE_EPNO_RSSI, 91 GSCAN_ATTRIBUTE_EPNO_FLAGS, 92 GSCAN_ATTRIBUTE_EPNO_AUTH, 93 GSCAN_ATTRIBUTE_EPNO_SSID_NUM, 94 GSCAN_ATTRIBUTE_EPNO_FLUSH, 95 96 /* remaining reserved for additional attributes */ 97 98 GSCAN_ATTRIBUTE_WHITELIST_SSID = 80, 99 GSCAN_ATTRIBUTE_NUM_WL_SSID, 100 GSCAN_ATTRIBUTE_WL_SSID_LEN, 101 GSCAN_ATTRIBUTE_WL_SSID_FLUSH, 102 GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM, 103 GSCAN_ATTRIBUTE_NUM_BSSID, 104 GSCAN_ATTRIBUTE_BSSID_PREF_LIST, 105 GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH, 106 GSCAN_ATTRIBUTE_BSSID_PREF, 107 GSCAN_ATTRIBUTE_RSSI_MODIFIER, 108 109 /* remaining reserved for additional attributes */ 110 111 GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90, 112 GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD, 113 GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR, 114 GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR, 115 GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST, 116 GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS, 117 GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER, 118 GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE, 119 120 /* BSSID blacklist */ 121 GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH = 100, 122 GSCAN_ATTRIBUTE_BLACKLIST_BSSID, 123 124 /* ANQPO */ 125 GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110, 126 GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, 127 GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, 128 GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, 129 GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID, 130 GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, 131 132 /* Adaptive scan attributes */ 133 GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120, 134 GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD, 135 136 /* ePNO cfg */ 137 GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR = 130, 138 GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR, 139 GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX, 140 GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS, 141 GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS, 142 GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS, 143 GSCAN_ATTRIBUTE_EPNO_5G_BONUS, 144 145 GSCAN_ATTRIBUTE_MAX 146 147 } GSCAN_ATTRIBUTE; 148 149 150 // helper methods 151 wifi_error wifi_enable_full_scan_results(wifi_request_id id, wifi_interface_handle iface, 152 wifi_scan_result_handler handler); 153 wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface); 154 int wifi_handle_full_scan_event(wifi_request_id id, WifiEvent& event, 155 wifi_scan_result_handler handler); 156 void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from); 157 158 159 void convert_to_hal_result(wifi_scan_result *to, wifi_gscan_result_t *from) 160 { 161 to->ts = from->ts; 162 to->channel = from->channel; 163 to->rssi = from->rssi; 164 to->rtt = from->rtt; 165 to->rtt_sd = from->rtt_sd; 166 to->beacon_period = from->beacon_period; 167 to->capability = from->capability; 168 memcpy(to->ssid, from->ssid, (DOT11_MAX_SSID_LEN+1)); 169 memcpy(&to->bssid, &from->bssid, sizeof(mac_addr)); 170 } 171 172 ///////////////////////////////////////////////////////////////////////////// 173 174 class GetCapabilitiesCommand : public WifiCommand 175 { 176 wifi_gscan_capabilities *mCapabilities; 177 public: 178 GetCapabilitiesCommand(wifi_interface_handle iface, wifi_gscan_capabilities *capabitlites) 179 : WifiCommand("GetGscanCapabilitiesCommand", iface, 0), mCapabilities(capabitlites) 180 { 181 memset(mCapabilities, 0, sizeof(*mCapabilities)); 182 } 183 184 virtual int create() { 185 ALOGV("Creating message to get scan capablities; iface = %d", mIfaceInfo->id); 186 187 int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CAPABILITIES); 188 if (ret < 0) { 189 return ret; 190 } 191 192 return ret; 193 } 194 195 protected: 196 virtual int handleResponse(WifiEvent& reply) { 197 198 ALOGV("In GetCapabilities::handleResponse"); 199 200 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 201 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 202 return NL_SKIP; 203 } 204 205 int id = reply.get_vendor_id(); 206 int subcmd = reply.get_vendor_subcmd(); 207 208 void *data = reply.get_vendor_data(); 209 int len = reply.get_vendor_data_len(); 210 211 ALOGV("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len, 212 sizeof(*mCapabilities)); 213 214 memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities))); 215 216 return NL_OK; 217 } 218 }; 219 220 221 wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, 222 wifi_gscan_capabilities *capabilities) 223 { 224 GetCapabilitiesCommand command(handle, capabilities); 225 return (wifi_error) command.requestResponse(); 226 } 227 228 class GetChannelListCommand : public WifiCommand 229 { 230 wifi_channel *channels; 231 int max_channels; 232 int *num_channels; 233 int band; 234 public: 235 GetChannelListCommand(wifi_interface_handle iface, wifi_channel *channel_buf, int *ch_num, 236 int num_max_ch, int band) 237 : WifiCommand("GetChannelListCommand", iface, 0), channels(channel_buf), 238 max_channels(num_max_ch), num_channels(ch_num), band(band) 239 { 240 memset(channels, 0, sizeof(wifi_channel) * max_channels); 241 } 242 virtual int create() { 243 ALOGV("Creating message to get channel list; iface = %d", mIfaceInfo->id); 244 245 int ret = mMsg.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_CHANNEL_LIST); 246 if (ret < 0) { 247 return ret; 248 } 249 250 nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA); 251 ret = mMsg.put_u32(GSCAN_ATTRIBUTE_BAND, band); 252 if (ret < 0) { 253 return ret; 254 } 255 256 mMsg.attr_end(data); 257 258 return ret; 259 } 260 261 protected: 262 virtual int handleResponse(WifiEvent& reply) { 263 264 ALOGV("In GetChannelList::handleResponse"); 265 266 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 267 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 268 return NL_SKIP; 269 } 270 271 int id = reply.get_vendor_id(); 272 int subcmd = reply.get_vendor_subcmd(); 273 int num_channels_to_copy = 0; 274 275 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 276 int len = reply.get_vendor_data_len(); 277 278 ALOGV("Id = %0x, subcmd = %d, len = %d", id, subcmd, len); 279 if (vendor_data == NULL || len == 0) { 280 ALOGE("no vendor data in GetChannelList response; ignoring it"); 281 return NL_SKIP; 282 } 283 284 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 285 if (it.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS) { 286 num_channels_to_copy = it.get_u32(); 287 ALOGI("Got channel list with %d channels", num_channels_to_copy); 288 if(num_channels_to_copy > max_channels) 289 num_channels_to_copy = max_channels; 290 *num_channels = num_channels_to_copy; 291 } else if (it.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST && num_channels_to_copy) { 292 memcpy(channels, it.get_data(), sizeof(int) * num_channels_to_copy); 293 } else { 294 ALOGW("Ignoring invalid attribute type = %d, size = %d", 295 it.get_type(), it.get_len()); 296 } 297 } 298 299 return NL_OK; 300 } 301 }; 302 303 wifi_error wifi_get_valid_channels(wifi_interface_handle handle, 304 int band, int max_channels, wifi_channel *channels, int *num_channels) 305 { 306 GetChannelListCommand command(handle, channels, num_channels, 307 max_channels, band); 308 return (wifi_error) command.requestResponse(); 309 } 310 ///////////////////////////////////////////////////////////////////////////// 311 312 /* helper functions */ 313 314 static int parseScanResults(wifi_scan_result *results, int num, nlattr *attr) 315 { 316 memset(results, 0, sizeof(wifi_scan_result) * num); 317 318 int i = 0; 319 for (nl_iterator it(attr); it.has_next() && i < num; it.next(), i++) { 320 321 int index = it.get_type(); 322 ALOGI("retrieved scan result %d", index); 323 nlattr *sc_data = (nlattr *) it.get_data(); 324 wifi_scan_result *result = results + i; 325 326 for (nl_iterator it2(sc_data); it2.has_next(); it2.next()) { 327 int type = it2.get_type(); 328 if (type == GSCAN_ATTRIBUTE_SSID) { 329 strncpy(result->ssid, (char *) it2.get_data(), it2.get_len()); 330 result->ssid[it2.get_len()] = 0; 331 } else if (type == GSCAN_ATTRIBUTE_BSSID) { 332 memcpy(result->bssid, (byte *) it2.get_data(), sizeof(mac_addr)); 333 } else if (type == GSCAN_ATTRIBUTE_TIMESTAMP) { 334 result->ts = it2.get_u64(); 335 } else if (type == GSCAN_ATTRIBUTE_CHANNEL) { 336 result->ts = it2.get_u16(); 337 } else if (type == GSCAN_ATTRIBUTE_RSSI) { 338 result->rssi = it2.get_u8(); 339 } else if (type == GSCAN_ATTRIBUTE_RTT) { 340 result->rtt = it2.get_u64(); 341 } else if (type == GSCAN_ATTRIBUTE_RTTSD) { 342 result->rtt_sd = it2.get_u64(); 343 } 344 } 345 346 } 347 348 if (i >= num) { 349 ALOGE("Got too many results; skipping some"); 350 } 351 352 return i; 353 } 354 355 int createFeatureRequest(WifiRequest& request, int subcmd, int enable) { 356 357 int result = request.create(GOOGLE_OUI, subcmd); 358 if (result < 0) { 359 return result; 360 } 361 362 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 363 result = request.put_u32(GSCAN_ATTRIBUTE_ENABLE_FEATURE, enable); 364 if (result < 0) { 365 return result; 366 } 367 368 request.attr_end(data); 369 return WIFI_SUCCESS; 370 } 371 372 ///////////////////////////////////////////////////////////////////////////// 373 class FullScanResultsCommand : public WifiCommand 374 { 375 int *mParams; 376 wifi_scan_result_handler mHandler; 377 public: 378 FullScanResultsCommand(wifi_interface_handle iface, int id, int *params, 379 wifi_scan_result_handler handler) 380 : WifiCommand("FullScanResultsCommand", iface, id), mParams(params), mHandler(handler) 381 { } 382 383 int createRequest(WifiRequest& request, int subcmd, int enable) { 384 int result = request.create(GOOGLE_OUI, subcmd); 385 if (result < 0) { 386 return result; 387 } 388 389 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 390 result = request.put_u32(GSCAN_ENABLE_FULL_SCAN_RESULTS, enable); 391 if (result < 0) { 392 return result; 393 } 394 395 request.attr_end(data); 396 return WIFI_SUCCESS; 397 398 } 399 400 int start() { 401 ALOGV("Enabling Full scan results"); 402 WifiRequest request(familyId(), ifaceId()); 403 int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 1); 404 if (result != WIFI_SUCCESS) { 405 ALOGE("failed to create request; result = %d", result); 406 return result; 407 } 408 409 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 410 411 result = requestResponse(request); 412 if (result != WIFI_SUCCESS) { 413 ALOGE("failed to enable full scan results; result = %d", result); 414 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 415 return result; 416 } 417 418 return result; 419 } 420 421 virtual int cancel() { 422 ALOGV("Disabling Full scan results"); 423 424 WifiRequest request(familyId(), ifaceId()); 425 int result = createRequest(request, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, 0); 426 if (result != WIFI_SUCCESS) { 427 ALOGE("failed to create request; result = %d", result); 428 } else { 429 result = requestResponse(request); 430 if (result != WIFI_SUCCESS) { 431 ALOGE("failed to disable full scan results;result = %d", result); 432 } 433 } 434 435 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 436 return WIFI_SUCCESS; 437 } 438 439 virtual int handleResponse(WifiEvent& reply) { 440 ALOGD("Request complete!"); 441 /* Nothing to do on response! */ 442 return NL_SKIP; 443 } 444 445 virtual int handleEvent(WifiEvent& event) { 446 ALOGV("Full scan results: Got an event"); 447 return wifi_handle_full_scan_event(id(), event, mHandler); 448 } 449 450 }; 451 ///////////////////////////////////////////////////////////////////////////// 452 453 class ScanCommand : public WifiCommand 454 { 455 wifi_scan_cmd_params *mParams; 456 wifi_scan_result_handler mHandler; 457 public: 458 ScanCommand(wifi_interface_handle iface, int id, wifi_scan_cmd_params *params, 459 wifi_scan_result_handler handler) 460 : WifiCommand("ScanCommand", iface, id), mParams(params), mHandler(handler) 461 { } 462 463 int createSetupRequest(WifiRequest& request) { 464 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_CONFIG); 465 if (result < 0) { 466 return result; 467 } 468 469 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 470 result = request.put_u32(GSCAN_ATTRIBUTE_BASE_PERIOD, mParams->base_period); 471 if (result < 0) { 472 return result; 473 } 474 475 result = request.put_u32(GSCAN_ATTRIBUTE_NUM_BUCKETS, mParams->num_buckets); 476 if (result < 0) { 477 return result; 478 } 479 480 for (int i = 0; i < mParams->num_buckets; i++) { 481 nlattr * bucket = request.attr_start(i); // next bucket 482 result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID, mParams->buckets[i].bucket); 483 if (result < 0) { 484 return result; 485 } 486 result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_PERIOD, mParams->buckets[i].period); 487 if (result < 0) { 488 return result; 489 } 490 result = request.put_u32(GSCAN_ATTRIBUTE_BUCKETS_BAND, 491 mParams->buckets[i].band); 492 if (result < 0) { 493 return result; 494 } 495 result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT, 496 mParams->buckets[i].step_count); 497 if (result < 0) { 498 return result; 499 } 500 result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD, 501 mParams->buckets[i].max_period); 502 if (result < 0) { 503 return result; 504 } 505 result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_EVENTS, 506 mParams->buckets[i].report_events); 507 if (result < 0) { 508 return result; 509 } 510 511 result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, 512 mParams->buckets[i].num_channels); 513 if (result < 0) { 514 return result; 515 } 516 517 if (mParams->buckets[i].num_channels) { 518 nlattr *channels = request.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS); 519 ALOGV(" channels: "); 520 for (int j = 0; j < mParams->buckets[i].num_channels; j++) { 521 result = request.put_u32(j, mParams->buckets[i].channels[j].channel); 522 ALOGV(" %u", mParams->buckets[i].channels[j].channel); 523 524 if (result < 0) { 525 return result; 526 } 527 } 528 request.attr_end(channels); 529 } 530 531 request.attr_end(bucket); 532 } 533 534 request.attr_end(data); 535 return WIFI_SUCCESS; 536 } 537 538 int createScanConfigRequest(WifiRequest& request) { 539 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SCAN_CONFIG); 540 if (result < 0) { 541 return result; 542 } 543 544 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 545 result = request.put_u32(GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, mParams->max_ap_per_scan); 546 if (result < 0) { 547 return result; 548 } 549 550 result = request.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD, 551 mParams->report_threshold_percent); 552 if (result < 0) { 553 return result; 554 } 555 556 int num_scans = mParams->report_threshold_num_scans; 557 558 result = request.put_u32(GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, num_scans); 559 if (result < 0) { 560 return result; 561 } 562 563 request.attr_end(data); 564 return WIFI_SUCCESS; 565 } 566 567 int createStartRequest(WifiRequest& request) { 568 return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 569 } 570 571 int createStopRequest(WifiRequest& request) { 572 return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0); 573 } 574 575 int start() { 576 ALOGV("GSCAN start"); 577 WifiRequest request(familyId(), ifaceId()); 578 int result = createSetupRequest(request); 579 if (result != WIFI_SUCCESS) { 580 ALOGE("failed to create setup request; result = %d", result); 581 return result; 582 } 583 584 result = requestResponse(request); 585 if (result != WIFI_SUCCESS) { 586 ALOGE("failed to configure setup; result = %d", result); 587 return result; 588 } 589 590 request.destroy(); 591 592 result = createScanConfigRequest(request); 593 if (result != WIFI_SUCCESS) { 594 ALOGE("failed to create scan config request; result = %d", result); 595 return result; 596 } 597 598 result = requestResponse(request); 599 if (result != WIFI_SUCCESS) { 600 ALOGE("failed to configure scan; result = %d", result); 601 return result; 602 } 603 604 ALOGV(" ....starting scan"); 605 606 result = createStartRequest(request); 607 if (result != WIFI_SUCCESS) { 608 ALOGE("failed to create start request; result = %d", result); 609 return result; 610 } 611 612 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 613 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 614 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 615 616 result = requestResponse(request); 617 if (result != WIFI_SUCCESS) { 618 ALOGE("failed to start scan; result = %d", result); 619 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 620 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 621 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 622 return result; 623 } 624 return result; 625 } 626 627 virtual int cancel() { 628 ALOGV("Stopping scan"); 629 630 WifiRequest request(familyId(), ifaceId()); 631 int result = createStopRequest(request); 632 if (result != WIFI_SUCCESS) { 633 ALOGE("failed to create stop request; result = %d", result); 634 } else { 635 result = requestResponse(request); 636 if (result != WIFI_SUCCESS) { 637 ALOGE("failed to stop scan; result = %d", result); 638 } 639 } 640 641 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); 642 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); 643 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); 644 return WIFI_SUCCESS; 645 } 646 647 virtual int handleResponse(WifiEvent& reply) { 648 /* Nothing to do on response! */ 649 return NL_SKIP; 650 } 651 652 virtual int handleEvent(WifiEvent& event) { 653 ALOGV("Got a scan results event"); 654 //event.log(); 655 656 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 657 int len = event.get_vendor_data_len(); 658 int event_id = event.get_vendor_subcmd(); 659 660 if ((event_id == GSCAN_EVENT_COMPLETE_SCAN) || 661 (event_id == GSCAN_EVENT_SCAN_RESULTS_AVAILABLE)) { 662 if (vendor_data == NULL || len != 4) { 663 ALOGI("Bad event data!"); 664 return NL_SKIP; 665 } 666 wifi_scan_event evt_type; 667 evt_type = (wifi_scan_event) event.get_u32(NL80211_ATTR_VENDOR_DATA); 668 ALOGV("Received event type %d", evt_type); 669 if(*mHandler.on_scan_event) 670 (*mHandler.on_scan_event)(id(), evt_type); 671 } else if (event_id == GSCAN_EVENT_FULL_SCAN_RESULTS) { 672 wifi_handle_full_scan_event(id(), event, mHandler); 673 } 674 return NL_SKIP; 675 } 676 }; 677 678 wifi_error wifi_start_gscan( 679 wifi_request_id id, 680 wifi_interface_handle iface, 681 wifi_scan_cmd_params params, 682 wifi_scan_result_handler handler) 683 { 684 wifi_handle handle = getWifiHandle(iface); 685 686 ALOGV("Starting GScan, halHandle = %p", handle); 687 688 ScanCommand *cmd = new ScanCommand(iface, id, ¶ms, handler); 689 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 690 wifi_error result = wifi_register_cmd(handle, id, cmd); 691 if (result != WIFI_SUCCESS) { 692 cmd->releaseRef(); 693 return result; 694 } 695 result = (wifi_error)cmd->start(); 696 if (result != WIFI_SUCCESS) { 697 wifi_unregister_cmd(handle, id); 698 cmd->releaseRef(); 699 return result; 700 } 701 return result; 702 } 703 704 wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface) 705 { 706 wifi_handle handle = getWifiHandle(iface); 707 ALOGV("Stopping GScan, wifi_request_id = %d, halHandle = %p", id, handle); 708 709 if (id == -1) { 710 wifi_scan_result_handler handler; 711 wifi_scan_cmd_params dummy_params; 712 wifi_handle handle = getWifiHandle(iface); 713 memset(&handler, 0, sizeof(handler)); 714 715 ScanCommand *cmd = new ScanCommand(iface, id, &dummy_params, handler); 716 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 717 cmd->cancel(); 718 cmd->releaseRef(); 719 return WIFI_SUCCESS; 720 } 721 722 return wifi_cancel_cmd(id, iface); 723 } 724 725 wifi_error wifi_enable_full_scan_results( 726 wifi_request_id id, 727 wifi_interface_handle iface, 728 wifi_scan_result_handler handler) 729 { 730 wifi_handle handle = getWifiHandle(iface); 731 int params_dummy; 732 733 ALOGV("Enabling full scan results, halHandle = %p", handle); 734 735 FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, id, ¶ms_dummy, handler); 736 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 737 wifi_error result = wifi_register_cmd(handle, id, cmd); 738 if (result != WIFI_SUCCESS) { 739 cmd->releaseRef(); 740 return result; 741 } 742 result = (wifi_error)cmd->start(); 743 if (result != WIFI_SUCCESS) { 744 wifi_unregister_cmd(handle, id); 745 cmd->releaseRef(); 746 return result; 747 } 748 return result; 749 } 750 751 int wifi_handle_full_scan_event( 752 wifi_request_id id, 753 WifiEvent& event, 754 wifi_scan_result_handler handler) 755 { 756 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 757 unsigned int len = event.get_vendor_data_len(); 758 759 if (vendor_data == NULL || len < sizeof(wifi_gscan_full_result_t)) { 760 ALOGI("Full scan results: No scan results found"); 761 return NL_SKIP; 762 } 763 764 wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data(); 765 /* To protect against corrupted data, put a ceiling */ 766 int ie_len = min(MAX_PROBE_RESP_IE_LEN, drv_res->ie_length); 767 wifi_scan_result *full_scan_result; 768 wifi_gscan_result_t *fixed = &drv_res->fixed; 769 770 if ((ie_len + offsetof(wifi_gscan_full_result_t, ie_data)) > len) { 771 ALOGE("BAD event data, len %d ie_len %d fixed length %d!\n", len, 772 ie_len, offsetof(wifi_gscan_full_result_t, ie_data)); 773 return NL_SKIP; 774 } 775 full_scan_result = (wifi_scan_result *) malloc((ie_len + offsetof(wifi_scan_result, ie_data))); 776 if (!full_scan_result) { 777 ALOGE("Full scan results: Can't malloc!\n"); 778 return NL_SKIP; 779 } 780 convert_to_hal_result(full_scan_result, fixed); 781 full_scan_result->ie_length = ie_len; 782 memcpy(full_scan_result->ie_data, drv_res->ie_data, ie_len); 783 if(handler.on_full_scan_result) 784 handler.on_full_scan_result(id, full_scan_result, drv_res->scan_ch_bucket); 785 786 ALOGV("Full scan result: %-32s %02x:%02x:%02x:%02x:%02x:%02x %d %d %lld %lld %lld %x %d\n", 787 fixed->ssid, fixed->bssid[0], fixed->bssid[1], fixed->bssid[2], fixed->bssid[3], 788 fixed->bssid[4], fixed->bssid[5], fixed->rssi, fixed->channel, fixed->ts, 789 fixed->rtt, fixed->rtt_sd, drv_res->scan_ch_bucket, drv_res->ie_length); 790 free(full_scan_result); 791 return NL_SKIP; 792 } 793 794 795 wifi_error wifi_disable_full_scan_results(wifi_request_id id, wifi_interface_handle iface) 796 { 797 ALOGV("Disabling full scan results"); 798 wifi_handle handle = getWifiHandle(iface); 799 800 if(id == -1) { 801 wifi_scan_result_handler handler; 802 wifi_handle handle = getWifiHandle(iface); 803 int params_dummy; 804 805 memset(&handler, 0, sizeof(handler)); 806 FullScanResultsCommand *cmd = new FullScanResultsCommand(iface, 0, ¶ms_dummy, handler); 807 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 808 cmd->cancel(); 809 cmd->releaseRef(); 810 return WIFI_SUCCESS; 811 } 812 813 return wifi_cancel_cmd(id, iface); 814 } 815 816 817 ///////////////////////////////////////////////////////////////////////////// 818 819 class GetScanResultsCommand : public WifiCommand { 820 wifi_cached_scan_results *mScans; 821 int mMax; 822 int *mNum; 823 int mRetrieved; 824 byte mFlush; 825 int mCompleted; 826 public: 827 GetScanResultsCommand(wifi_interface_handle iface, byte flush, 828 wifi_cached_scan_results *results, int max, int *num) 829 : WifiCommand("GetScanResultsCommand", iface, -1), mScans(results), mMax(max), mNum(num), 830 mRetrieved(0), mFlush(flush), mCompleted(0) 831 { } 832 833 int createRequest(WifiRequest& request, int num, byte flush) { 834 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_GET_SCAN_RESULTS); 835 if (result < 0) { 836 return result; 837 } 838 839 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 840 result = request.put_u32(GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num); 841 if (result < 0) { 842 return result; 843 } 844 845 result = request.put_u8(GSCAN_ATTRIBUTE_FLUSH_RESULTS, flush); 846 if (result < 0) { 847 return result; 848 } 849 850 request.attr_end(data); 851 return WIFI_SUCCESS; 852 } 853 854 int execute() { 855 WifiRequest request(familyId(), ifaceId()); 856 ALOGV("retrieving %d scan results", mMax); 857 858 for (int i = 0; i < 10 && mRetrieved < mMax; i++) { 859 int num_to_retrieve = mMax - mRetrieved; 860 // ALOGI("retrieving %d scan results in one shot", num_to_retrieve); 861 int result = createRequest(request, num_to_retrieve, mFlush); 862 if (result < 0) { 863 ALOGE("failed to create request"); 864 return result; 865 } 866 867 int prev_retrieved = mRetrieved; 868 869 result = requestResponse(request); 870 871 if (result != WIFI_SUCCESS) { 872 ALOGE("failed to retrieve scan results; result = %d", result); 873 return result; 874 } 875 876 if (mRetrieved == prev_retrieved || mCompleted) { 877 /* no more items left to retrieve */ 878 break; 879 } 880 881 request.destroy(); 882 } 883 884 ALOGV("GetScanResults read %d results", mRetrieved); 885 *mNum = mRetrieved; 886 return WIFI_SUCCESS; 887 } 888 889 virtual int handleResponse(WifiEvent& reply) { 890 ALOGV("In GetScanResultsCommand::handleResponse"); 891 892 if (reply.get_cmd() != NL80211_CMD_VENDOR) { 893 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); 894 return NL_SKIP; 895 } 896 897 int id = reply.get_vendor_id(); 898 int subcmd = reply.get_vendor_subcmd(); 899 900 ALOGV("Id = %0x, subcmd = %d", id, subcmd); 901 902 /* 903 if (subcmd != GSCAN_SUBCMD_SCAN_RESULTS) { 904 ALOGE("Invalid response to GetScanResultsCommand; ignoring it"); 905 return NL_SKIP; 906 } 907 */ 908 909 nlattr *vendor_data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA); 910 int len = reply.get_vendor_data_len(); 911 912 if (vendor_data == NULL || len == 0) { 913 ALOGE("no vendor data in GetScanResults response; ignoring it"); 914 return NL_SKIP; 915 } 916 917 for (nl_iterator it(vendor_data); it.has_next(); it.next()) { 918 if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE) { 919 mCompleted = it.get_u8(); 920 ALOGV("retrieved mCompleted flag : %d", mCompleted); 921 } else if (it.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS || it.get_type() == 0) { 922 int scan_id = 0, flags = 0, num = 0, scan_ch_bucket_mask = 0; 923 for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) { 924 if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_ID) { 925 scan_id = it2.get_u32(); 926 ALOGV("retrieved scan_id : 0x%0x", scan_id); 927 } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS) { 928 flags = it2.get_u8(); 929 ALOGV("retrieved scan_flags : 0x%0x", flags); 930 } else if (it2.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { 931 num = it2.get_u32(); 932 ALOGV("retrieved num_results: %d", num); 933 } else if (it2.get_type() == GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK) { 934 scan_ch_bucket_mask = it2.get_u32(); 935 ALOGD("retrieved scan_ch_bucket_mask: %x", scan_ch_bucket_mask); 936 } else if (it2.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS && num) { 937 if (mRetrieved >= mMax) { 938 ALOGW("Stored %d scans, ignoring excess results", mRetrieved); 939 break; 940 } 941 num = min(num, (int)(it2.get_len()/sizeof(wifi_gscan_result))); 942 num = min(num, (int)MAX_AP_CACHE_PER_SCAN); 943 ALOGV("Copying %d scan results", num); 944 wifi_gscan_result_t *results = (wifi_gscan_result_t *)it2.get_data(); 945 wifi_scan_result *mScanResults = mScans[mRetrieved].results; 946 947 for (int i = 0; i < num; i++) { 948 wifi_gscan_result_t *result = &results[i]; 949 convert_to_hal_result(&mScanResults[i], result); 950 mScanResults[i].ie_length = 0; 951 ALOGV("%02d %-32s %02x:%02x:%02x:%02x:%02x:%02x %04d", i, 952 result->ssid, result->bssid[0], result->bssid[1], result->bssid[2], 953 result->bssid[3], result->bssid[4], result->bssid[5], 954 result->rssi); 955 } 956 mScans[mRetrieved].scan_id = scan_id; 957 mScans[mRetrieved].flags = flags; 958 mScans[mRetrieved].num_results = num; 959 mScans[mRetrieved].buckets_scanned = scan_ch_bucket_mask; 960 ALOGV("Setting result of scan_id : 0x%0x", mScans[mRetrieved].scan_id); 961 mRetrieved++; 962 } else { 963 ALOGW("Ignoring invalid attribute type = %d, size = %d", 964 it.get_type(), it.get_len()); 965 } 966 } 967 } else { 968 ALOGW("Ignoring invalid attribute type = %d, size = %d", 969 it.get_type(), it.get_len()); 970 } 971 } 972 ALOGV("GetScanResults read %d results", mRetrieved); 973 return NL_OK; 974 } 975 }; 976 977 wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush, 978 int max, wifi_cached_scan_results *results, int *num) { 979 ALOGV("Getting cached scan results, iface handle = %p, num = %d", iface, *num); 980 981 GetScanResultsCommand *cmd = new GetScanResultsCommand(iface, flush, results, max, num); 982 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 983 wifi_error err = (wifi_error)cmd->execute(); 984 cmd->releaseRef(); 985 return err; 986 } 987 988 ///////////////////////////////////////////////////////////////////////////// 989 990 class BssidHotlistCommand : public WifiCommand 991 { 992 private: 993 wifi_bssid_hotlist_params mParams; 994 wifi_hotlist_ap_found_handler mHandler; 995 static const int MAX_RESULTS = 64; 996 wifi_scan_result mResults[MAX_RESULTS]; 997 public: 998 BssidHotlistCommand(wifi_interface_handle handle, int id, 999 wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) 1000 : WifiCommand("BssidHotlistCommand", handle, id), mParams(params), mHandler(handler) 1001 { } 1002 1003 int createSetupRequest(WifiRequest& request) { 1004 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST); 1005 if (result < 0) { 1006 return result; 1007 } 1008 1009 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1010 result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1); 1011 if (result < 0) { 1012 return result; 1013 } 1014 1015 result = request.put_u32(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size); 1016 if (result < 0) { 1017 return result; 1018 } 1019 1020 result = request.put_u32(GSCAN_ATTRIBUTE_HOTLIST_BSSID_COUNT, mParams.num_bssid); 1021 if (result < 0) { 1022 return result; 1023 } 1024 1025 struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS); 1026 for (int i = 0; i < mParams.num_bssid; i++) { 1027 nlattr *attr2 = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_ELEM); 1028 if (attr2 == NULL) { 1029 return WIFI_ERROR_OUT_OF_MEMORY; 1030 } 1031 result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid); 1032 if (result < 0) { 1033 return result; 1034 } 1035 result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high); 1036 if (result < 0) { 1037 return result; 1038 } 1039 result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low); 1040 if (result < 0) { 1041 return result; 1042 } 1043 request.attr_end(attr2); 1044 } 1045 1046 request.attr_end(attr); 1047 request.attr_end(data); 1048 return result; 1049 } 1050 1051 int createTeardownRequest(WifiRequest& request) { 1052 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_HOTLIST); 1053 if (result < 0) { 1054 return result; 1055 } 1056 1057 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1058 result = request.put_u8(GSCAN_ATTRIBUTE_HOTLIST_FLUSH, 1); 1059 if (result < 0) { 1060 return result; 1061 } 1062 1063 struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS); 1064 request.attr_end(attr); 1065 request.attr_end(data); 1066 return result; 1067 } 1068 1069 int start() { 1070 ALOGI("Executing hotlist setup request, num = %d", mParams.num_bssid); 1071 WifiRequest request(familyId(), ifaceId()); 1072 int result = createSetupRequest(request); 1073 if (result < 0) { 1074 return result; 1075 } 1076 1077 result = requestResponse(request); 1078 if (result < 0) { 1079 ALOGI("Failed to execute hotlist setup request, result = %d", result); 1080 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1081 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 1082 return result; 1083 } 1084 1085 ALOGI("Successfully set %d APs in the hotlist ", mParams.num_bssid); 1086 result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 1087 if (result < 0) { 1088 return result; 1089 } 1090 1091 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1092 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 1093 1094 result = requestResponse(request); 1095 if (result < 0) { 1096 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1097 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 1098 return result; 1099 } 1100 1101 ALOGI("successfully restarted the scan"); 1102 return result; 1103 } 1104 1105 virtual int cancel() { 1106 /* unregister event handler */ 1107 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); 1108 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); 1109 /* create set hotlist message with empty hotlist */ 1110 WifiRequest request(familyId(), ifaceId()); 1111 int result = createTeardownRequest(request); 1112 if (result < 0) { 1113 return result; 1114 } 1115 1116 result = requestResponse(request); 1117 if (result < 0) { 1118 return result; 1119 } 1120 1121 ALOGI("Successfully reset APs in current hotlist"); 1122 return result; 1123 } 1124 1125 virtual int handleResponse(WifiEvent& reply) { 1126 /* Nothing to do on response! */ 1127 return NL_SKIP; 1128 } 1129 1130 virtual int handleEvent(WifiEvent& event) { 1131 ALOGI("Hotlist AP event"); 1132 int event_id = event.get_vendor_subcmd(); 1133 // event.log(); 1134 1135 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 1136 int len = event.get_vendor_data_len(); 1137 1138 if (vendor_data == NULL || len == 0) { 1139 ALOGI("No scan results found"); 1140 return NL_SKIP; 1141 } 1142 1143 memset(mResults, 0, sizeof(wifi_scan_result) * MAX_RESULTS); 1144 1145 int num = len / sizeof(wifi_gscan_result_t); 1146 wifi_gscan_result_t *inp = (wifi_gscan_result_t *)event.get_vendor_data(); 1147 num = min(MAX_RESULTS, num); 1148 for (int i = 0; i < num; i++, inp++) { 1149 convert_to_hal_result(&(mResults[i]), inp); 1150 } 1151 1152 if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_FOUND) { 1153 ALOGI("FOUND %d hotlist APs", num); 1154 if (*mHandler.on_hotlist_ap_found) 1155 (*mHandler.on_hotlist_ap_found)(id(), num, mResults); 1156 } else if (event_id == GSCAN_EVENT_HOTLIST_RESULTS_LOST) { 1157 ALOGI("LOST %d hotlist APs", num); 1158 if (*mHandler.on_hotlist_ap_lost) 1159 (*mHandler.on_hotlist_ap_lost)(id(), num, mResults); 1160 } 1161 return NL_SKIP; 1162 } 1163 }; 1164 1165 class ePNOCommand : public WifiCommand 1166 { 1167 private: 1168 wifi_epno_params epno_params; 1169 wifi_epno_handler mHandler; 1170 wifi_scan_result mResults[MAX_EPNO_NETWORKS]; 1171 public: 1172 ePNOCommand(wifi_interface_handle handle, int id, 1173 const wifi_epno_params *params, wifi_epno_handler handler) 1174 : WifiCommand("ePNOCommand", handle, id), mHandler(handler) 1175 { 1176 if (params != NULL) { 1177 memcpy(&epno_params, params, sizeof(wifi_epno_params)); 1178 } else { 1179 memset(&epno_params, 0, sizeof(wifi_epno_params)); 1180 } 1181 } 1182 int createSetupRequest(WifiRequest& request) { 1183 if (epno_params.num_networks > MAX_EPNO_NETWORKS) { 1184 ALOGE("wrong epno num_networks:%d", epno_params.num_networks); 1185 return WIFI_ERROR_INVALID_ARGS; 1186 } 1187 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID); 1188 if (result < 0) { 1189 return result; 1190 } 1191 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1192 result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1); 1193 if (result < 0) { 1194 return result; 1195 } 1196 1197 result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_5G_RSSI_THR, 1198 (u8)epno_params.min5GHz_rssi); 1199 if (result < 0) { 1200 return result; 1201 } 1202 result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_2G_RSSI_THR, 1203 (u8)epno_params.min24GHz_rssi); 1204 if (result < 0) { 1205 return result; 1206 } 1207 result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_INIT_SCORE_MAX, 1208 epno_params.initial_score_max); 1209 if (result < 0) { 1210 return result; 1211 } 1212 result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_CUR_CONN_BONUS, 1213 epno_params.current_connection_bonus); 1214 if (result < 0) { 1215 return result; 1216 } 1217 result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS, 1218 epno_params.same_network_bonus); 1219 if (result < 0) { 1220 return result; 1221 } 1222 result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_SECURE_BONUS, 1223 epno_params.secure_bonus); 1224 if (result < 0) { 1225 return result; 1226 } 1227 result = request.put_u16(GSCAN_ATTRIBUTE_EPNO_5G_BONUS, 1228 epno_params.band5GHz_bonus); 1229 if (result < 0) { 1230 return result; 1231 } 1232 result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_SSID_NUM, 1233 epno_params.num_networks); 1234 if (result < 0) { 1235 return result; 1236 } 1237 struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_EPNO_SSID_LIST); 1238 wifi_epno_network *ssid_list = epno_params.networks; 1239 for (int i = 0; i < epno_params.num_networks; i++) { 1240 nlattr *attr2 = request.attr_start(i); 1241 if (attr2 == NULL) { 1242 return WIFI_ERROR_OUT_OF_MEMORY; 1243 } 1244 result = request.put(GSCAN_ATTRIBUTE_EPNO_SSID, ssid_list[i].ssid, DOT11_MAX_SSID_LEN); 1245 ALOGI("PNO network: SSID %s flags %x auth %x", ssid_list[i].ssid, 1246 ssid_list[i].flags, 1247 ssid_list[i].auth_bit_field); 1248 if (result < 0) { 1249 return result; 1250 } 1251 result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_SSID_LEN, strlen(ssid_list[i].ssid)); 1252 if (result < 0) { 1253 return result; 1254 } 1255 result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_FLAGS, ssid_list[i].flags); 1256 if (result < 0) { 1257 return result; 1258 } 1259 result = request.put_u32(GSCAN_ATTRIBUTE_EPNO_AUTH, ssid_list[i].auth_bit_field); 1260 if (result < 0) { 1261 return result; 1262 } 1263 request.attr_end(attr2); 1264 } 1265 request.attr_end(attr); 1266 request.attr_end(data); 1267 return result; 1268 } 1269 1270 int createTeardownRequest(WifiRequest& request) { 1271 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_EPNO_SSID); 1272 if (result < 0) { 1273 return result; 1274 } 1275 1276 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1277 result = request.put_u8(GSCAN_ATTRIBUTE_EPNO_FLUSH, 1); 1278 if (result < 0) { 1279 return result; 1280 } 1281 request.attr_end(data); 1282 return result; 1283 } 1284 1285 int start() { 1286 ALOGI("Executing ePNO setup request, num = %d", epno_params.num_networks); 1287 WifiRequest request(familyId(), ifaceId()); 1288 int result = createSetupRequest(request); 1289 if (result < 0) { 1290 return result; 1291 } 1292 1293 result = requestResponse(request); 1294 if (result < 0) { 1295 ALOGI("Failed to execute ePNO setup request, result = %d", result); 1296 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); 1297 return result; 1298 } 1299 1300 ALOGI("Successfully set %d SSIDs for ePNO", epno_params.num_networks); 1301 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); 1302 ALOGI("successfully restarted the scan"); 1303 return result; 1304 } 1305 1306 virtual int cancel() { 1307 /* unregister event handler */ 1308 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); 1309 /* create set hotlist message with empty hotlist */ 1310 WifiRequest request(familyId(), ifaceId()); 1311 int result = createTeardownRequest(request); 1312 if (result < 0) { 1313 return result; 1314 } 1315 1316 result = requestResponse(request); 1317 if (result < 0) { 1318 return result; 1319 } 1320 1321 ALOGI("Successfully reset APs in current hotlist"); 1322 return result; 1323 } 1324 1325 virtual int handleResponse(WifiEvent& reply) { 1326 /* Nothing to do on response! */ 1327 return NL_SKIP; 1328 } 1329 1330 virtual int handleEvent(WifiEvent& event) { 1331 ALOGI("ePNO event"); 1332 int event_id = event.get_vendor_subcmd(); 1333 // event.log(); 1334 1335 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 1336 int len = event.get_vendor_data_len(); 1337 1338 if (vendor_data == NULL || len == 0) { 1339 ALOGI("No scan results found"); 1340 return NL_SKIP; 1341 } 1342 1343 memset(mResults, 0, sizeof(wifi_scan_result) * MAX_EPNO_NETWORKS); 1344 1345 unsigned int num = len / sizeof(wifi_pno_result_t); 1346 unsigned int i; 1347 num = min(MAX_EPNO_NETWORKS, num); 1348 wifi_pno_result_t *res = (wifi_pno_result_t *) event.get_vendor_data(); 1349 for (i = 0; i < num; i++) { 1350 if (res[i].flags == PNO_SSID_FOUND) { 1351 memcpy(mResults[i].ssid, res[i].ssid, res[i].ssid_len); 1352 memcpy(mResults[i].bssid, res[i].bssid, sizeof(mac_addr)); 1353 1354 mResults[i].ssid[res[i].ssid_len] = '\0'; 1355 mResults[i].channel = res[i].channel; 1356 mResults[i].rssi = res[i].rssi; 1357 } 1358 } 1359 if (*mHandler.on_network_found) 1360 (*mHandler.on_network_found)(id(), num, mResults); 1361 return NL_SKIP; 1362 } 1363 }; 1364 1365 wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface, 1366 wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) 1367 { 1368 wifi_handle handle = getWifiHandle(iface); 1369 1370 BssidHotlistCommand *cmd = new BssidHotlistCommand(iface, id, params, handler); 1371 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1372 wifi_error result = wifi_register_cmd(handle, id, cmd); 1373 if (result != WIFI_SUCCESS) { 1374 cmd->releaseRef(); 1375 return result; 1376 } 1377 result = (wifi_error)cmd->start(); 1378 if (result != WIFI_SUCCESS) { 1379 wifi_unregister_cmd(handle, id); 1380 cmd->releaseRef(); 1381 return result; 1382 } 1383 return result; 1384 } 1385 1386 wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface) 1387 { 1388 return wifi_cancel_cmd(id, iface); 1389 } 1390 1391 1392 ///////////////////////////////////////////////////////////////////////////// 1393 1394 class SignificantWifiChangeCommand : public WifiCommand 1395 { 1396 typedef struct { 1397 mac_addr bssid; // BSSID 1398 wifi_channel channel; // channel frequency in MHz 1399 int num_rssi; // number of rssi samples 1400 wifi_rssi rssi[8]; // RSSI history in db 1401 } wifi_significant_change_result_internal; 1402 1403 private: 1404 wifi_significant_change_params mParams; 1405 wifi_significant_change_handler mHandler; 1406 static const int MAX_RESULTS = 64; 1407 wifi_significant_change_result_internal mResultsBuffer[MAX_RESULTS]; 1408 wifi_significant_change_result *mResults[MAX_RESULTS]; 1409 public: 1410 SignificantWifiChangeCommand(wifi_interface_handle handle, int id, 1411 wifi_significant_change_params params, wifi_significant_change_handler handler) 1412 : WifiCommand("SignificantWifiChangeCommand", handle, id), mParams(params), 1413 mHandler(handler) 1414 { } 1415 1416 int createSetupRequest(WifiRequest& request) { 1417 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); 1418 if (result < 0) { 1419 return result; 1420 } 1421 1422 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1423 result = request.put_u8(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1); 1424 if (result < 0) { 1425 return result; 1426 } 1427 result = request.put_u16(GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE, mParams.rssi_sample_size); 1428 if (result < 0) { 1429 return result; 1430 } 1431 result = request.put_u16(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, mParams.lost_ap_sample_size); 1432 if (result < 0) { 1433 return result; 1434 } 1435 result = request.put_u16(GSCAN_ATTRIBUTE_MIN_BREACHING, mParams.min_breaching); 1436 if (result < 0) { 1437 return result; 1438 } 1439 result = request.put_u16(GSCAN_ATTRIBUTE_NUM_BSSID, mParams.num_bssid); 1440 if (result < 0) { 1441 return result; 1442 } 1443 if (mParams.num_bssid != 0) { 1444 nlattr* attr = request.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS); 1445 if (attr == NULL) { 1446 return WIFI_ERROR_OUT_OF_MEMORY; 1447 } 1448 1449 for (int i = 0; i < mParams.num_bssid; i++) { 1450 nlattr* attr2 = request.attr_start(i); 1451 if (attr2 == NULL) { 1452 return WIFI_ERROR_OUT_OF_MEMORY; 1453 } 1454 result = request.put_addr(GSCAN_ATTRIBUTE_BSSID, mParams.ap[i].bssid); 1455 if (result < 0) { 1456 return result; 1457 } 1458 result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH, mParams.ap[i].high); 1459 if (result < 0) { 1460 return result; 1461 } 1462 result = request.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW, mParams.ap[i].low); 1463 if (result < 0) { 1464 return result; 1465 } 1466 request.attr_end(attr2); 1467 } 1468 1469 request.attr_end(attr); 1470 } 1471 request.attr_end(data); 1472 1473 return result; 1474 } 1475 1476 int createTeardownRequest(WifiRequest& request) { 1477 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); 1478 if (result < 0) { 1479 return result; 1480 } 1481 1482 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1483 result = request.put_u16(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, 1); 1484 if (result < 0) { 1485 return result; 1486 } 1487 1488 request.attr_end(data); 1489 return result; 1490 } 1491 1492 int start() { 1493 ALOGI("Set significant wifi change config"); 1494 WifiRequest request(familyId(), ifaceId()); 1495 1496 int result = createSetupRequest(request); 1497 if (result < 0) { 1498 return result; 1499 } 1500 1501 result = requestResponse(request); 1502 if (result < 0) { 1503 ALOGI("failed to set significant wifi change config %d", result); 1504 return result; 1505 } 1506 1507 ALOGI("successfully set significant wifi change config"); 1508 1509 result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); 1510 if (result < 0) { 1511 return result; 1512 } 1513 1514 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 1515 1516 result = requestResponse(request); 1517 if (result < 0) { 1518 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 1519 return result; 1520 } 1521 1522 ALOGI("successfully restarted the scan"); 1523 return result; 1524 } 1525 1526 virtual int cancel() { 1527 /* unregister event handler */ 1528 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); 1529 1530 /* create set significant change monitor message with empty hotlist */ 1531 WifiRequest request(familyId(), ifaceId()); 1532 1533 int result = createTeardownRequest(request); 1534 if (result < 0) { 1535 return result; 1536 } 1537 1538 result = requestResponse(request); 1539 if (result < 0) { 1540 return result; 1541 } 1542 1543 ALOGI("successfully reset significant wifi change config"); 1544 return result; 1545 } 1546 1547 virtual int handleResponse(WifiEvent& reply) { 1548 /* Nothing to do on response! */ 1549 return NL_SKIP; 1550 } 1551 1552 virtual int handleEvent(WifiEvent& event) { 1553 ALOGV("Got a significant wifi change event"); 1554 1555 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 1556 int len = event.get_vendor_data_len(); 1557 1558 if (vendor_data == NULL || len == 0) { 1559 ALOGI("No scan results found"); 1560 return NL_SKIP; 1561 } 1562 1563 typedef struct { 1564 uint16_t flags; 1565 uint16_t channel; 1566 mac_addr bssid; 1567 s8 rssi_history[8]; 1568 } ChangeInfo; 1569 1570 int num = min(len / sizeof(ChangeInfo), MAX_RESULTS); 1571 ChangeInfo *ci = (ChangeInfo *)event.get_vendor_data(); 1572 1573 for (int i = 0; i < num; i++) { 1574 memcpy(mResultsBuffer[i].bssid, ci[i].bssid, sizeof(mac_addr)); 1575 mResultsBuffer[i].channel = ci[i].channel; 1576 mResultsBuffer[i].num_rssi = 8; 1577 for (int j = 0; j < mResultsBuffer[i].num_rssi; j++) 1578 mResultsBuffer[i].rssi[j] = (int) ci[i].rssi_history[j]; 1579 mResults[i] = reinterpret_cast<wifi_significant_change_result *>(&(mResultsBuffer[i])); 1580 } 1581 1582 ALOGV("Retrieved %d scan results", num); 1583 1584 if (num != 0) { 1585 (*mHandler.on_significant_change)(id(), num, mResults); 1586 } else { 1587 ALOGW("No significant change reported"); 1588 } 1589 1590 return NL_SKIP; 1591 } 1592 }; 1593 1594 wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface, 1595 wifi_significant_change_params params, wifi_significant_change_handler handler) 1596 { 1597 wifi_handle handle = getWifiHandle(iface); 1598 1599 SignificantWifiChangeCommand *cmd = new SignificantWifiChangeCommand( 1600 iface, id, params, handler); 1601 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1602 wifi_error result = wifi_register_cmd(handle, id, cmd); 1603 if (result != WIFI_SUCCESS) { 1604 cmd->releaseRef(); 1605 return result; 1606 } 1607 result = (wifi_error)cmd->start(); 1608 if (result != WIFI_SUCCESS) { 1609 wifi_unregister_cmd(handle, id); 1610 cmd->releaseRef(); 1611 return result; 1612 } 1613 return result; 1614 } 1615 1616 wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface) 1617 { 1618 return wifi_cancel_cmd(id, iface); 1619 } 1620 1621 wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface) 1622 { 1623 if (id == -1) { 1624 wifi_epno_handler handler; 1625 wifi_handle handle = getWifiHandle(iface); 1626 1627 memset(&handler, 0, sizeof(handler)); 1628 ePNOCommand *cmd = new ePNOCommand(iface, id, NULL, handler); 1629 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1630 cmd->cancel(); 1631 cmd->releaseRef(); 1632 return WIFI_SUCCESS; 1633 } 1634 return wifi_cancel_cmd(id, iface); 1635 } 1636 1637 wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface, 1638 const wifi_epno_params *params, wifi_epno_handler handler) 1639 { 1640 wifi_handle handle = getWifiHandle(iface); 1641 1642 ePNOCommand *cmd = new ePNOCommand(iface, id, params, handler); 1643 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1644 wifi_error result = wifi_register_cmd(handle, id, cmd); 1645 if (result != WIFI_SUCCESS) { 1646 cmd->releaseRef(); 1647 return result; 1648 } 1649 result = (wifi_error)cmd->start(); 1650 if (result != WIFI_SUCCESS) { 1651 wifi_unregister_cmd(handle, id); 1652 cmd->releaseRef(); 1653 return result; 1654 } 1655 return result; 1656 } 1657 1658 1659 //////////////////////////////////////////////////////////////////////////////// 1660 1661 class AnqpoConfigureCommand : public WifiCommand 1662 { 1663 int num_hs; 1664 wifi_passpoint_network *mNetworks; 1665 wifi_passpoint_event_handler mHandler; 1666 wifi_scan_result *mResult; 1667 public: 1668 AnqpoConfigureCommand(wifi_request_id id, wifi_interface_handle iface, 1669 int num, wifi_passpoint_network *hs_list, wifi_passpoint_event_handler handler) 1670 : WifiCommand("AnqpoConfigureCommand", iface, id), num_hs(num), mNetworks(hs_list), 1671 mHandler(handler) 1672 { 1673 mResult = NULL; 1674 } 1675 1676 int createRequest(WifiRequest& request, int val) { 1677 1678 int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_ANQPO_CONFIG); 1679 result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, num_hs); 1680 if (result < 0) { 1681 return result; 1682 } 1683 1684 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); 1685 1686 struct nlattr * attr = request.attr_start(GSCAN_ATTRIBUTE_ANQPO_HS_LIST); 1687 for (int i = 0; i < num_hs; i++) { 1688 nlattr *attr2 = request.attr_start(i); 1689 if (attr2 == NULL) { 1690 return WIFI_ERROR_OUT_OF_MEMORY; 1691 } 1692 result = request.put_u32(GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, mNetworks[i].id); 1693 if (result < 0) { 1694 return result; 1695 } 1696 result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, mNetworks[i].realm, 256); 1697 if (result < 0) { 1698 return result; 1699 } 1700 result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID, 1701 mNetworks[i].roamingConsortiumIds, 128); 1702 if (result < 0) { 1703 return result; 1704 } 1705 result = request.put(GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, mNetworks[i].plmn, 3); 1706 if (result < 0) { 1707 return result; 1708 } 1709 1710 request.attr_end(attr2); 1711 } 1712 1713 request.attr_end(attr); 1714 request.attr_end(data); 1715 1716 return WIFI_SUCCESS; 1717 } 1718 1719 int start() { 1720 1721 WifiRequest request(familyId(), ifaceId()); 1722 int result = createRequest(request, num_hs); 1723 if (result != WIFI_SUCCESS) { 1724 ALOGE("failed to create request; result = %d", result); 1725 return result; 1726 } 1727 1728 registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); 1729 1730 result = requestResponse(request); 1731 if (result != WIFI_SUCCESS) { 1732 ALOGE("failed to set ANQPO networks; result = %d", result); 1733 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); 1734 return result; 1735 } 1736 1737 return result; 1738 } 1739 1740 virtual int cancel() { 1741 1742 WifiRequest request(familyId(), ifaceId()); 1743 int result = createRequest(request, 0); 1744 if (result != WIFI_SUCCESS) { 1745 ALOGE("failed to create request; result = %d", result); 1746 } else { 1747 result = requestResponse(request); 1748 if (result != WIFI_SUCCESS) { 1749 ALOGE("failed to reset ANQPO networks;result = %d", result); 1750 } 1751 } 1752 1753 unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); 1754 return WIFI_SUCCESS; 1755 } 1756 1757 virtual int handleResponse(WifiEvent& reply) { 1758 ALOGD("Request complete!"); 1759 /* Nothing to do on response! */ 1760 return NL_SKIP; 1761 } 1762 1763 virtual int handleEvent(WifiEvent& event) { 1764 typedef struct { 1765 u16 channel; /* channel of GAS protocol */ 1766 u8 dialog_token; /* GAS dialog token */ 1767 u8 fragment_id; /* fragment id */ 1768 u16 status_code; /* status code on GAS completion */ 1769 u16 data_len; /* length of data to follow */ 1770 u8 data[1]; /* variable length specified by data_len */ 1771 } wifi_anqp_gas_resp; 1772 1773 ALOGI("ANQPO hotspot matched event!"); 1774 1775 nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); 1776 unsigned int len = event.get_vendor_data_len(); 1777 1778 if (vendor_data == NULL || len < sizeof(wifi_scan_result)) { 1779 ALOGI("No scan results found"); 1780 return NL_SKIP; 1781 } 1782 mResult = (wifi_scan_result *)malloc(sizeof(wifi_scan_result)); 1783 if (!mResult) { 1784 return NL_SKIP; 1785 } 1786 wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data(); 1787 wifi_gscan_result_t *fixed = &drv_res->fixed; 1788 convert_to_hal_result(mResult, fixed); 1789 1790 byte *anqp = (byte *)drv_res + offsetof(wifi_gscan_full_result_t, ie_data) + drv_res->ie_length; 1791 wifi_anqp_gas_resp *gas = (wifi_anqp_gas_resp *)anqp; 1792 int anqp_len = offsetof(wifi_anqp_gas_resp, data) + gas->data_len; 1793 int networkId = *(int *)((byte *)anqp + anqp_len); 1794 1795 ALOGI("%-32s\t", mResult->ssid); 1796 1797 ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", mResult->bssid[0], mResult->bssid[1], 1798 mResult->bssid[2], mResult->bssid[3], mResult->bssid[4], mResult->bssid[5]); 1799 1800 ALOGI("%d\t", mResult->rssi); 1801 ALOGI("%d\t", mResult->channel); 1802 ALOGI("%lld\t", mResult->ts); 1803 ALOGI("%lld\t", mResult->rtt); 1804 ALOGI("%lld\n", mResult->rtt_sd); 1805 1806 if(*mHandler.on_passpoint_network_found) 1807 (*mHandler.on_passpoint_network_found)(id(), networkId, mResult, anqp_len, anqp); 1808 free(mResult); 1809 return NL_SKIP; 1810 } 1811 }; 1812 1813 wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num, 1814 wifi_passpoint_network *networks, wifi_passpoint_event_handler handler) 1815 { 1816 wifi_handle handle = getWifiHandle(iface); 1817 1818 AnqpoConfigureCommand *cmd = new AnqpoConfigureCommand(id, iface, num, networks, handler); 1819 NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); 1820 wifi_error result = wifi_register_cmd(handle, id, cmd); 1821 if (result != WIFI_SUCCESS) { 1822 cmd->releaseRef(); 1823 return result; 1824 } 1825 result = (wifi_error)cmd->start(); 1826 if (result != WIFI_SUCCESS) { 1827 wifi_unregister_cmd(handle, id); 1828 cmd->releaseRef(); 1829 return result; 1830 } 1831 return result; 1832 } 1833 1834 wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface) 1835 { 1836 return wifi_cancel_cmd(id, iface); 1837 } 1838