5 #include <sys/socket.h>
6 #include <netlink/genl/genl.h>
7 #include <netlink/genl/family.h>
8 #include <netlink/genl/ctrl.h>
9 #include <linux/rtnetlink.h>
10 #include <netpacket/packet.h>
11 #include <linux/filter.h>
12 #include <linux/errqueue.h>
14 #include <linux/pkt_sched.h>
15 #include <netlink/object-api.h>
16 #include <netlink/netlink.h>
17 #include <netlink/socket.h>
18 #include <netlink/handlers.h>
22 #define LOG_TAG "WifiHAL"
24 #include <utils/Log.h>
28 #include "cpp_bindings.h"
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_REPORT_THRESHOLD_NUM_SCANS
,
43 GSCAN_ATTRIBUTE_BAND
= GSCAN_ATTRIBUTE_BUCKETS_BAND
,
45 GSCAN_ATTRIBUTE_ENABLE_FEATURE
= 20,
46 GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE
, /* indicates no more results */
47 GSCAN_ATTRIBUTE_REPORT_EVENTS
,
49 /* remaining reserved for additional attributes */
50 GSCAN_ATTRIBUTE_NUM_OF_RESULTS
= 30,
51 GSCAN_ATTRIBUTE_SCAN_RESULTS
, /* flat array of wifi_scan_result */
52 GSCAN_ATTRIBUTE_NUM_CHANNELS
,
53 GSCAN_ATTRIBUTE_CHANNEL_LIST
,
54 GSCAN_ATTRIBUTE_SCAN_ID
,
55 GSCAN_ATTRIBUTE_SCAN_FLAGS
,
57 /* remaining reserved for additional attributes */
59 GSCAN_ATTRIBUTE_SSID
= 40,
60 GSCAN_ATTRIBUTE_BSSID
,
61 GSCAN_ATTRIBUTE_CHANNEL
,
63 GSCAN_ATTRIBUTE_TIMESTAMP
,
65 GSCAN_ATTRIBUTE_RTTSD
,
67 /* remaining reserved for additional attributes */
69 GSCAN_ATTRIBUTE_HOTLIST_BSSIDS
= 50,
70 GSCAN_ATTRIBUTE_RSSI_LOW
,
71 GSCAN_ATTRIBUTE_RSSI_HIGH
,
72 GSCAN_ATTRIBUTE_HOTLIST_ELEM
,
73 GSCAN_ATTRIBUTE_HOTLIST_FLUSH
,
74 GSCAN_ATTRIBUTE_CHANNEL_NUMBER
,
76 /* remaining reserved for additional attributes */
77 GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE
= 60,
78 GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE
,
79 GSCAN_ATTRIBUTE_MIN_BREACHING
,
80 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS
,
82 GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT
= 70,
83 GSCAN_ATTRIBUTE_BUCKET_EXPONENT
,
84 GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD
,
86 GSCAN_ATTRIBUTE_NUM_BSSID
,
87 GSCAN_ATTRIBUTE_BLACKLIST_BSSID
,
94 EPNO_ATTRIBUTE_SSID_LIST
,
95 EPNO_ATTRIBUTE_SSID_NUM
,
97 EPNO_ATTRIBUTE_SSID_LEN
,
105 EPNO_ATTRIBUTE_HS_PARAM_LIST
,
106 EPNO_ATTRIBUTE_HS_NUM
,
107 EPNO_ATTRIBUTE_HS_ID
,
108 EPNO_ATTRIBUTE_HS_REALM
,
109 EPNO_ATTRIBUTE_HS_CONSORTIUM_IDS
,
110 EPNO_ATTRIBUTE_HS_PLMN
,
111 EPNO_ATTRIBUTE_HS_MAX
115 class GetCapabilitiesCommand
: public WifiCommand
117 wifi_gscan_capabilities
*mCapabilities
;
119 GetCapabilitiesCommand(wifi_interface_handle iface
, wifi_gscan_capabilities
*capabitlites
)
120 : WifiCommand(iface
, 0), mCapabilities(capabitlites
)
122 memset(mCapabilities
, 0, sizeof(*mCapabilities
));
125 virtual int create() {
126 ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo
->id
);
128 int ret
= mMsg
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_GET_CAPABILITIES
);
130 ALOGD("NL message creation failed");
138 virtual int handleResponse(WifiEvent
& reply
) {
140 ALOGD("In GetCapabilities::handleResponse");
142 if (reply
.get_cmd() != NL80211_CMD_VENDOR
) {
143 ALOGD("Ignoring reply with cmd = %d", reply
.get_cmd());
147 int id
= reply
.get_vendor_id();
148 int subcmd
= reply
.get_vendor_subcmd();
150 void *data
= reply
.get_vendor_data();
151 int len
= reply
.get_vendor_data_len();
153 ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id
, subcmd
, len
,
154 sizeof(*mCapabilities
));
156 memcpy(mCapabilities
, data
, min(len
, (int) sizeof(*mCapabilities
)));
163 wifi_error
wifi_get_gscan_capabilities(wifi_interface_handle handle
,
164 wifi_gscan_capabilities
*capabilities
)
166 GetCapabilitiesCommand
command(handle
, capabilities
);
167 return (wifi_error
) command
.requestResponse();
170 class GetChannelListCommand
: public WifiCommand
172 wifi_channel
*channels
;
177 GetChannelListCommand(wifi_interface_handle iface
, wifi_channel
*channel_buf
, int *ch_num
,
178 int num_max_ch
, int band
)
179 : WifiCommand(iface
, 0), channels(channel_buf
), max_channels(num_max_ch
), num_channels(ch_num
),
182 memset(channels
, 0, sizeof(wifi_channel
) * max_channels
);
184 virtual int create() {
185 ALOGD("Creating message to get channel list; iface = %d", mIfaceInfo
->id
);
187 int ret
= mMsg
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_GET_VALID_CHANNELS
);
192 nlattr
*data
= mMsg
.attr_start(NL80211_ATTR_VENDOR_DATA
);
193 ret
= mMsg
.put_u32(GSCAN_ATTRIBUTE_BAND
, band
);
204 virtual int handleResponse(WifiEvent
& reply
) {
206 ALOGD("In GetChannelList::handleResponse");
208 if (reply
.get_cmd() != NL80211_CMD_VENDOR
) {
209 ALOGD("Ignoring reply with cmd = %d", reply
.get_cmd());
213 int id
= reply
.get_vendor_id();
214 int subcmd
= reply
.get_vendor_subcmd();
215 int num_channels_to_copy
= 0;
217 nlattr
*vendor_data
= reply
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
218 int len
= reply
.get_vendor_data_len();
220 ALOGD("Id = %0x, subcmd = %d, len = %d", id
, subcmd
, len
);
221 if (vendor_data
== NULL
|| len
== 0) {
222 ALOGE("no vendor data in GetChannelList response; ignoring it");
226 for (nl_iterator
it(vendor_data
); it
.has_next(); it
.next()) {
227 if (it
.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS
) {
228 num_channels_to_copy
= it
.get_u32();
229 ALOGD("Got channel list with %d channels", num_channels_to_copy
);
230 if(num_channels_to_copy
> max_channels
)
231 num_channels_to_copy
= max_channels
;
232 *num_channels
= num_channels_to_copy
;
233 } else if (it
.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST
&& num_channels_to_copy
) {
234 memcpy(channels
, it
.get_data(), sizeof(int) * num_channels_to_copy
);
236 ALOGW("Ignoring invalid attribute type = %d, size = %d",
237 it
.get_type(), it
.get_len());
245 wifi_error
wifi_get_valid_channels(wifi_interface_handle handle
,
246 int band
, int max_channels
, wifi_channel
*channels
, int *num_channels
)
248 GetChannelListCommand
command(handle
, channels
, num_channels
,
250 return (wifi_error
) command
.requestResponse();
252 /////////////////////////////////////////////////////////////////////////////
254 /* helper functions */
256 static int parseScanResults(wifi_scan_result
*results
, int num
, nlattr
*attr
)
258 memset(results
, 0, sizeof(wifi_scan_result
) * num
);
261 for (nl_iterator
it(attr
); it
.has_next() && i
< num
; it
.next(), i
++) {
263 int index
= it
.get_type();
264 ALOGD("retrieved scan result %d", index
);
265 nlattr
*sc_data
= (nlattr
*) it
.get_data();
266 wifi_scan_result
*result
= results
+ i
;
268 for (nl_iterator
it2(sc_data
); it2
.has_next(); it2
.next()) {
269 int type
= it2
.get_type();
270 if (type
== GSCAN_ATTRIBUTE_SSID
) {
271 strncpy(result
->ssid
, (char *) it2
.get_data(), it2
.get_len());
272 result
->ssid
[it2
.get_len()] = 0;
273 } else if (type
== GSCAN_ATTRIBUTE_BSSID
) {
274 memcpy(result
->bssid
, (byte
*) it2
.get_data(), sizeof(mac_addr
));
275 } else if (type
== GSCAN_ATTRIBUTE_TIMESTAMP
) {
276 result
->ts
= it2
.get_u64();
277 } else if (type
== GSCAN_ATTRIBUTE_CHANNEL
) {
278 result
->ts
= it2
.get_u16();
279 } else if (type
== GSCAN_ATTRIBUTE_RSSI
) {
280 result
->rssi
= it2
.get_u8();
281 } else if (type
== GSCAN_ATTRIBUTE_RTT
) {
282 result
->rtt
= it2
.get_u64();
283 } else if (type
== GSCAN_ATTRIBUTE_RTTSD
) {
284 result
->rtt_sd
= it2
.get_u64();
291 ALOGE("Got too many results; skipping some");
297 int createFeatureRequest(WifiRequest
& request
, int subcmd
) {
299 int result
= request
.create(GOOGLE_OUI
, subcmd
);
307 class ScanCommand
: public WifiCommand
309 wifi_scan_cmd_params
*mParams
;
310 wifi_scan_result_handler mHandler
;
311 static unsigned mGlobalFullScanBuckets
;
312 bool mLocalFullScanBuckets
;
314 ScanCommand(wifi_interface_handle iface
, int id
, wifi_scan_cmd_params
*params
,
315 wifi_scan_result_handler handler
)
316 : WifiCommand(iface
, id
), mParams(params
), mHandler(handler
),
317 mLocalFullScanBuckets(0)
320 int createSetupRequest(WifiRequest
& request
) {
321 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN
);
326 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
327 result
= request
.put_u32(GSCAN_ATTRIBUTE_BASE_PERIOD
, mParams
->base_period
);
332 result
= request
.put_u32(GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN
, mParams
->max_ap_per_scan
);
337 result
= request
.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD
, mParams
->report_threshold_percent
);
342 result
= request
.put_u32(GSCAN_ATTRIBUTE_REPORT_THRESHOLD_NUM_SCANS
, mParams
->report_threshold_num_scans
);
347 result
= request
.put_u32(GSCAN_ATTRIBUTE_NUM_BUCKETS
, mParams
->num_buckets
);
352 for (int i
= 0; i
< mParams
->num_buckets
; i
++) {
353 nlattr
* bucket
= request
.attr_start(i
); // next bucket
354 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID
, mParams
->buckets
[i
].bucket
);
358 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKET_PERIOD
, mParams
->buckets
[i
].period
);
362 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKETS_BAND
,
363 mParams
->buckets
[i
].band
);
368 result
= request
.put_u32(GSCAN_ATTRIBUTE_REPORT_EVENTS
,
369 mParams
->buckets
[i
].report_events
);
374 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS
,
375 mParams
->buckets
[i
].num_channels
);
380 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKET_EXPONENT
,
381 mParams
->buckets
[i
].exponent
);
386 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD
,
387 mParams
->buckets
[i
].max_period
);
392 result
= request
.put_u32(GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT
,
393 mParams
->buckets
[i
].step_count
);
398 if (mParams
->buckets
[i
].num_channels
) {
399 nlattr
*channels
= request
.attr_start(GSCAN_ATTRIBUTE_BUCKET_CHANNELS
);
400 for (int j
= 0; j
< mParams
->buckets
[i
].num_channels
; j
++) {
401 result
= request
.put_u32(j
, mParams
->buckets
[i
].channels
[j
].channel
);
406 request
.attr_end(channels
);
409 request
.attr_end(bucket
);
412 request
.attr_end(data
);
416 int createStartRequest(WifiRequest
& request
) {
417 return createFeatureRequest(request
, SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN
);
420 int createStopRequest(WifiRequest
& request
) {
421 return createFeatureRequest(request
, SLSI_NL80211_VENDOR_SUBCMD_DEL_GSCAN
);
425 ALOGD(" sending scan req to driver");
426 WifiRequest
request(familyId(), ifaceId());
427 int result
= createSetupRequest(request
);
428 if (result
!= WIFI_SUCCESS
) {
429 ALOGE("failed to create setup request; result = %d", result
);
432 ALOGD("Starting scan");
434 registerVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE
);
435 registerVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_COMPLETE_SCAN
);
438 for (int i
= 0; i
< mParams
->num_buckets
; i
++) {
439 if (mParams
->buckets
[i
].report_events
== 2) {
445 ALOGI("Full scan requested with nBuckets = %d", nBuckets
);
446 registerVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_FULL_SCAN_RESULTS
);
448 result
= requestResponse(request
);
449 if (result
!= WIFI_SUCCESS
) {
450 ALOGE("failed to start scan; result = %d", result
);
451 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_COMPLETE_SCAN
);
452 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE
);
460 virtual int cancel() {
461 ALOGD("Stopping scan");
463 WifiRequest
request(familyId(), ifaceId());
464 int result
= createStopRequest(request
);
465 if (result
!= WIFI_SUCCESS
) {
466 ALOGE("failed to create stop request; result = %d", result
);
468 result
= requestResponse(request
);
469 if (result
!= WIFI_SUCCESS
) {
470 ALOGE("failed to stop scan; result = %d", result
);
474 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_COMPLETE_SCAN
);
475 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE
);
476 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_FULL_SCAN_RESULTS
);
481 virtual int handleResponse(WifiEvent
& reply
) {
482 /* Nothing to do on response! */
486 virtual int handleEvent(WifiEvent
& event
) {
487 ALOGD("Got a scan results event");
491 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
492 unsigned int len
= event
.get_vendor_data_len();
493 int event_id
= event
.get_vendor_subcmd();
494 ALOGD("handleEvent, event_id = %d", event_id
);
496 if(event_id
== GSCAN_EVENT_COMPLETE_SCAN
) {
497 if (vendor_data
== NULL
|| len
!= 4) {
498 ALOGD("Scan complete type not mentioned!");
501 wifi_scan_event evt_type
;
503 evt_type
= (wifi_scan_event
) event
.get_u32(NL80211_ATTR_VENDOR_DATA
);
504 ALOGD("Scan complete: Received event type %d", evt_type
);
505 if(*mHandler
.on_scan_event
)
506 (*mHandler
.on_scan_event
)(evt_type
, evt_type
);
507 } else if(event_id
== GSCAN_EVENT_FULL_SCAN_RESULTS
) {
508 if (vendor_data
== NULL
|| len
< sizeof(wifi_scan_result
)) {
509 ALOGD("No scan results found");
512 wifi_scan_result
*result
= (wifi_scan_result
*)event
.get_vendor_data();
514 if(*mHandler
.on_full_scan_result
)
515 (*mHandler
.on_full_scan_result
)(id(), result
);
517 ALOGD("%-32s\t", result
->ssid
);
519 ALOGD("%02x:%02x:%02x:%02x:%02x:%02x ", result
->bssid
[0], result
->bssid
[1],
520 result
->bssid
[2], result
->bssid
[3], result
->bssid
[4], result
->bssid
[5]);
522 ALOGD("%d\t", result
->rssi
);
523 ALOGD("%d\t", result
->channel
);
524 ALOGD("%lld\t", result
->ts
);
525 ALOGD("%lld\t", result
->rtt
);
526 ALOGD("%lld\n", result
->rtt_sd
);
529 if (vendor_data
== NULL
|| len
!= 4) {
530 ALOGD("No scan results found");
534 int num
= event
.get_u32(NL80211_ATTR_VENDOR_DATA
);
535 ALOGD("Found %d scan results", num
);
536 if(*mHandler
.on_scan_results_available
)
537 (*mHandler
.on_scan_results_available
)(id(), num
);
543 unsigned ScanCommand::mGlobalFullScanBuckets
= 0;
545 wifi_error
wifi_start_gscan(
547 wifi_interface_handle iface
,
548 wifi_scan_cmd_params params
,
549 wifi_scan_result_handler handler
)
551 wifi_handle handle
= getWifiHandle(iface
);
553 ALOGD("Starting GScan, halHandle = %p", handle
);
555 ScanCommand
*cmd
= new ScanCommand(iface
, id
, ¶ms
, handler
);
556 wifi_register_cmd(handle
, id
, cmd
);
557 return (wifi_error
)cmd
->start();
560 wifi_error
wifi_stop_gscan(wifi_request_id id
, wifi_interface_handle iface
)
562 ALOGD("Stopping GScan");
563 wifi_handle handle
= getWifiHandle(iface
);
566 wifi_scan_result_handler handler
;
567 wifi_scan_cmd_params dummy_params
;
568 wifi_handle handle
= getWifiHandle(iface
);
569 memset(&handler
, 0, sizeof(handler
));
571 ScanCommand
*cmd
= new ScanCommand(iface
, id
, &dummy_params
, handler
);
578 WifiCommand
*cmd
= wifi_unregister_cmd(handle
, id
);
585 return WIFI_ERROR_INVALID_ARGS
;
588 class GetScanResultsCommand
: public WifiCommand
{
589 wifi_cached_scan_results
*mScans
;
595 static const int MAX_RESULTS
= 320;
596 wifi_scan_result mScanResults
[MAX_RESULTS
];
599 GetScanResultsCommand(wifi_interface_handle iface
, byte flush
,
600 wifi_cached_scan_results
*results
, int max
, int *num
)
601 : WifiCommand(iface
, -1), mScans(results
), mMax(max
), mNum(num
),
602 mRetrieved(0), mFlush(flush
), mCompleted(0)
605 int createRequest(WifiRequest
& request
, int num
, byte flush
) {
606 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_GET_SCAN_RESULTS
);
611 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
612 result
= request
.put_u32(GSCAN_ATTRIBUTE_NUM_OF_RESULTS
, num
);
617 request
.attr_end(data
);
622 WifiRequest
request(familyId(), ifaceId());
623 ALOGD("retrieving %d scan results", mMax
);
625 for (int i
= 0; i
< 10 && mRetrieved
< mMax
; i
++) {
626 int result
= createRequest(request
, (mMax
- mRetrieved
), mFlush
);
628 ALOGE("failed to create request");
632 int prev_retrieved
= mRetrieved
;
634 result
= requestResponse(request
);
636 if (result
!= WIFI_SUCCESS
) {
637 ALOGE("failed to retrieve scan results; result = %d", result
);
641 if (mRetrieved
== prev_retrieved
|| mCompleted
) {
642 /* no more items left to retrieve */
649 ALOGE("GetScanResults read %d results", mRetrieved
);
654 virtual int handleResponse(WifiEvent
& reply
) {
655 ALOGD("In GetScanResultsCommand::handleResponse");
657 if (reply
.get_cmd() != NL80211_CMD_VENDOR
) {
658 ALOGD("Ignoring reply with cmd = %d", reply
.get_cmd());
662 int id
= reply
.get_vendor_id();
663 int subcmd
= reply
.get_vendor_subcmd();
665 ALOGD("Id = %0x, subcmd = %d", id
, subcmd
);
667 nlattr
*vendor_data
= reply
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
668 int len
= reply
.get_vendor_data_len();
670 if (vendor_data
== NULL
|| len
== 0) {
671 ALOGE("no vendor data in GetScanResults response; ignoring it");
675 for (nl_iterator
it(vendor_data
); it
.has_next(); it
.next()) {
676 if (it
.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE
) {
677 mCompleted
= it
.get_u8();
678 ALOGD("retrieved mCompleted flag : %d", mCompleted
);
679 } else if (it
.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS
|| it
.get_type() == 0) {
680 int scan_id
= 0, flags
= 0, num
= 0;
681 for (nl_iterator
it2(it
.get()); it2
.has_next(); it2
.next()) {
682 if (it2
.get_type() == GSCAN_ATTRIBUTE_SCAN_ID
) {
683 scan_id
= it2
.get_u32();
684 ALOGD("retrieved scan_id : 0x%0x", scan_id
);
685 } else if (it2
.get_type() == GSCAN_ATTRIBUTE_SCAN_FLAGS
) {
686 flags
= it2
.get_u8();
687 ALOGD("retrieved scan_flags : 0x%0x", flags
);
688 } else if (it2
.get_type() == GSCAN_ATTRIBUTE_NUM_OF_RESULTS
) {
690 ALOGD("retrieved num_results: %d", num
);
691 } else if (it2
.get_type() == GSCAN_ATTRIBUTE_SCAN_RESULTS
) {
692 if (mRetrieved
>= mMax
) {
693 ALOGW("Stored %d scans, ignoring excess results", mRetrieved
);
696 num
= it2
.get_len() / sizeof(wifi_scan_result
);
697 num
= min(MAX_RESULTS
- mNextScanResult
, num
);
698 num
= min((int)MAX_AP_CACHE_PER_SCAN
, num
);
699 memcpy(mScanResults
+ mNextScanResult
, it2
.get_data(),
700 sizeof(wifi_scan_result
) * num
);
701 ALOGD("Retrieved %d scan results", num
);
702 wifi_scan_result
*results
= (wifi_scan_result
*)it2
.get_data();
703 for (int i
= 0; i
< num
; i
++) {
704 wifi_scan_result
*result
= results
+ i
;
705 ALOGD("%02d %-32s %02x:%02x:%02x:%02x:%02x:%02x %04d", i
,
706 result
->ssid
, result
->bssid
[0], result
->bssid
[1], result
->bssid
[2],
707 result
->bssid
[3], result
->bssid
[4], result
->bssid
[5],
710 mScans
[mRetrieved
].scan_id
= scan_id
;
711 mScans
[mRetrieved
].flags
= flags
;
712 mScans
[mRetrieved
].num_results
= num
;
713 ALOGD("Setting result of scan_id : 0x%0x", mScans
[mRetrieved
].scan_id
);
714 memcpy(mScans
[mRetrieved
].results
,
715 &(mScanResults
[mNextScanResult
]), num
* sizeof(wifi_scan_result
));
716 mNextScanResult
+= num
;
719 ALOGW("Ignoring invalid attribute type = %d, size = %d",
720 it
.get_type(), it
.get_len());
724 ALOGW("Ignoring invalid attribute type = %d, size = %d",
725 it
.get_type(), it
.get_len());
733 wifi_error
wifi_get_cached_gscan_results(wifi_interface_handle iface
, byte flush
,
734 int max
, wifi_cached_scan_results
*results
, int *num
) {
735 ALOGD("Getting cached scan results, iface handle = %p, num = %d", iface
, *num
);
737 GetScanResultsCommand
*cmd
= new GetScanResultsCommand(iface
, flush
, results
, max
, num
);
738 return (wifi_error
)cmd
->execute();
741 /////////////////////////////////////////////////////////////////////////////
743 class BssidHotlistCommand
: public WifiCommand
746 wifi_bssid_hotlist_params mParams
;
747 wifi_hotlist_ap_found_handler mHandler
;
748 static const int MAX_RESULTS
= 64;
749 wifi_scan_result mResults
[MAX_RESULTS
];
751 BssidHotlistCommand(wifi_interface_handle handle
, int id
,
752 wifi_bssid_hotlist_params params
, wifi_hotlist_ap_found_handler handler
)
753 : WifiCommand(handle
, id
), mParams(params
), mHandler(handler
)
756 int createSetupRequest(WifiRequest
& request
) {
757 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_HOTLIST
);
762 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
764 result
= request
.put_u32(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE
, mParams
.lost_ap_sample_size
);
769 struct nlattr
* attr
= request
.attr_start(GSCAN_ATTRIBUTE_HOTLIST_BSSIDS
);
770 for (int i
= 0; i
< mParams
.num_bssid
; i
++) {
771 nlattr
*attr2
= request
.attr_start(GSCAN_ATTRIBUTE_HOTLIST_ELEM
);
773 return WIFI_ERROR_OUT_OF_MEMORY
;
775 result
= request
.put_addr(GSCAN_ATTRIBUTE_BSSID
, mParams
.ap
[i
].bssid
);
779 result
= request
.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH
, mParams
.ap
[i
].high
);
783 result
= request
.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW
, mParams
.ap
[i
].low
);
787 request
.attr_end(attr2
);
790 request
.attr_end(attr
);
791 request
.attr_end(data
);
795 int createTeardownRequest(WifiRequest
& request
) {
796 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_RESET_BSSID_HOTLIST
);
805 ALOGD("Executing hotlist setup request, num = %d", mParams
.num_bssid
);
806 WifiRequest
request(familyId(), ifaceId());
807 int result
= createSetupRequest(request
);
812 result
= requestResponse(request
);
814 ALOGD("Failed to execute hotlist setup request, result = %d", result
);
815 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_HOTLIST_RESULTS_FOUND
);
816 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_HOTLIST_RESULTS_LOST
);
820 ALOGD("Successfully set %d APs in the hotlist", mParams
.num_bssid
);
822 registerVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_HOTLIST_RESULTS_FOUND
);
823 registerVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_HOTLIST_RESULTS_LOST
);
828 virtual int cancel() {
829 /* unregister event handler */
830 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_HOTLIST_RESULTS_FOUND
);
831 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_HOTLIST_RESULTS_LOST
);
832 /* create set hotlist message with empty hotlist */
833 WifiRequest
request(familyId(), ifaceId());
834 int result
= createTeardownRequest(request
);
839 result
= requestResponse(request
);
844 ALOGD("Successfully reset APs in current hotlist");
848 virtual int handleResponse(WifiEvent
& reply
) {
849 /* Nothing to do on response! */
853 virtual int handleEvent(WifiEvent
& event
) {
854 ALOGD("Hotlist AP event");
855 int event_id
= event
.get_vendor_subcmd();
858 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
859 int len
= event
.get_vendor_data_len();
861 if (vendor_data
== NULL
|| len
== 0) {
862 ALOGD("No scan results found");
866 memset(mResults
, 0, sizeof(wifi_scan_result
) * MAX_RESULTS
);
868 int num
= len
/ sizeof(wifi_scan_result
);
869 num
= min(MAX_RESULTS
, num
);
870 memcpy(mResults
, event
.get_vendor_data(), num
* sizeof(wifi_scan_result
));
872 if (event_id
== GSCAN_EVENT_HOTLIST_RESULTS_FOUND
) {
873 ALOGD("FOUND %d hotlist APs", num
);
874 if (*mHandler
.on_hotlist_ap_found
)
875 (*mHandler
.on_hotlist_ap_found
)(id(), num
, mResults
);
876 } else if (event_id
== GSCAN_EVENT_HOTLIST_RESULTS_LOST
) {
877 ALOGD("LOST %d hotlist APs", num
);
878 if (*mHandler
.on_hotlist_ap_lost
)
879 (*mHandler
.on_hotlist_ap_lost
)(id(), num
, mResults
);
885 wifi_error
wifi_set_bssid_hotlist(wifi_request_id id
, wifi_interface_handle iface
,
886 wifi_bssid_hotlist_params params
, wifi_hotlist_ap_found_handler handler
)
888 wifi_handle handle
= getWifiHandle(iface
);
890 BssidHotlistCommand
*cmd
= new BssidHotlistCommand(iface
, id
, params
, handler
);
891 wifi_register_cmd(handle
, id
, cmd
);
892 return (wifi_error
)cmd
->start();
895 wifi_error
wifi_reset_bssid_hotlist(wifi_request_id id
, wifi_interface_handle iface
)
897 wifi_handle handle
= getWifiHandle(iface
);
899 WifiCommand
*cmd
= wifi_unregister_cmd(handle
, id
);
906 return WIFI_ERROR_INVALID_ARGS
;
910 /////////////////////////////////////////////////////////////////////////////
912 class SignificantWifiChangeCommand
: public WifiCommand
915 mac_addr bssid
; // BSSID
916 wifi_channel channel
; // channel frequency in MHz
917 int num_rssi
; // number of rssi samples
918 wifi_rssi rssi
[8]; // RSSI history in db
919 } wifi_significant_change_result_internal
;
922 wifi_significant_change_params mParams
;
923 wifi_significant_change_handler mHandler
;
924 static const int MAX_RESULTS
= 64;
925 wifi_significant_change_result_internal mResultsBuffer
[MAX_RESULTS
];
926 wifi_significant_change_result
*mResults
[MAX_RESULTS
];
928 SignificantWifiChangeCommand(wifi_interface_handle handle
, int id
,
929 wifi_significant_change_params params
, wifi_significant_change_handler handler
)
930 : WifiCommand(handle
, id
), mParams(params
), mHandler(handler
)
933 int createSetupRequest(WifiRequest
& request
) {
934 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_SET_SIGNIFICANT_CHANGE
);
939 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
941 result
= request
.put_u16(GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE
, mParams
.rssi_sample_size
);
945 result
= request
.put_u16(GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE
, mParams
.lost_ap_sample_size
);
949 result
= request
.put_u16(GSCAN_ATTRIBUTE_MIN_BREACHING
, mParams
.min_breaching
);
954 struct nlattr
* attr
= request
.attr_start(GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS
);
956 for (int i
= 0; i
< mParams
.num_bssid
; i
++) {
958 nlattr
*attr2
= request
.attr_start(i
);
960 return WIFI_ERROR_OUT_OF_MEMORY
;
962 result
= request
.put_addr(GSCAN_ATTRIBUTE_BSSID
, mParams
.ap
[i
].bssid
);
966 result
= request
.put_u8(GSCAN_ATTRIBUTE_RSSI_HIGH
, mParams
.ap
[i
].high
);
970 result
= request
.put_u8(GSCAN_ATTRIBUTE_RSSI_LOW
, mParams
.ap
[i
].low
);
974 request
.attr_end(attr2
);
977 request
.attr_end(attr
);
978 request
.attr_end(data
);
983 int createTeardownRequest(WifiRequest
& request
) {
984 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_RESET_SIGNIFICANT_CHANGE
);
993 ALOGD("Set significant wifi change");
994 WifiRequest
request(familyId(), ifaceId());
996 int result
= createSetupRequest(request
);
1001 result
= requestResponse(request
);
1003 ALOGD("failed to set significant wifi change %d", result
);
1006 registerVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS
);
1011 virtual int cancel() {
1012 /* unregister event handler */
1013 unregisterVendorHandler(GOOGLE_OUI
, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS
);
1015 /* create set significant change monitor message with empty hotlist */
1016 WifiRequest
request(familyId(), ifaceId());
1018 int result
= createTeardownRequest(request
);
1023 result
= requestResponse(request
);
1028 ALOGD("successfully reset significant wifi change");
1032 virtual int handleResponse(WifiEvent
& reply
) {
1033 /* Nothing to do on response! */
1037 virtual int handleEvent(WifiEvent
& event
) {
1038 ALOGD("Got a significant wifi change event");
1040 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
1041 int len
= event
.get_vendor_data_len();
1043 if (vendor_data
== NULL
|| len
== 0) {
1044 ALOGD("No scan results found");
1051 int16_t rssi_history
[8];
1054 int num
= min(len
/ sizeof(ChangeInfo
), MAX_RESULTS
);
1055 ChangeInfo
*ci
= (ChangeInfo
*)event
.get_vendor_data();
1057 for (int i
= 0; i
< num
; i
++) {
1058 memcpy(mResultsBuffer
[i
].bssid
, ci
[i
].bssid
, sizeof(mac_addr
));
1059 mResultsBuffer
[i
].channel
= ci
[i
].channel
;
1060 /* Driver sends N samples and the rest 8-N are filled 0x7FFF
1061 * N = no of rssi samples to average sent in significant change request. */
1063 for (int j
= 0; j
< 8; j
++) {
1064 if (ci
[i
].rssi_history
[j
] == 0x7FFF) {
1068 mResultsBuffer
[i
].rssi
[j
] = (int) ci
[i
].rssi_history
[j
];
1070 mResultsBuffer
[i
].num_rssi
= num_rssi
;
1071 mResults
[i
] = reinterpret_cast<wifi_significant_change_result
*>(&(mResultsBuffer
[i
]));
1074 ALOGD("Retrieved %d scan results", num
);
1077 (*mHandler
.on_significant_change
)(id(), num
, mResults
);
1079 ALOGW("No significant change reported");
1086 wifi_error
wifi_set_significant_change_handler(wifi_request_id id
, wifi_interface_handle iface
,
1087 wifi_significant_change_params params
, wifi_significant_change_handler handler
)
1089 wifi_handle handle
= getWifiHandle(iface
);
1091 SignificantWifiChangeCommand
*cmd
= new SignificantWifiChangeCommand(
1092 iface
, id
, params
, handler
);
1093 wifi_register_cmd(handle
, id
, cmd
);
1094 return (wifi_error
)cmd
->start();
1097 wifi_error
wifi_reset_significant_change_handler(wifi_request_id id
, wifi_interface_handle iface
)
1099 wifi_handle handle
= getWifiHandle(iface
);
1101 WifiCommand
*cmd
= wifi_unregister_cmd(handle
, id
);
1105 return WIFI_SUCCESS
;
1108 return WIFI_ERROR_INVALID_ARGS
;
1111 class ePNOCommand
: public WifiCommand
1114 wifi_epno_network
*ssid_list
;
1116 wifi_epno_handler mHandler
;
1117 wifi_scan_result mResults
;
1119 ePNOCommand(wifi_interface_handle handle
, int id
,
1120 int num_networks
, wifi_epno_network
*networks
, wifi_epno_handler handler
)
1121 : WifiCommand(handle
, id
), mHandler(handler
)
1123 ssid_list
= networks
;
1124 num_ssid
= num_networks
;
1127 int createSetupRequest(WifiRequest
& request
) {
1128 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_SET_EPNO_LIST
);
1133 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
1135 result
= request
.put_u8(EPNO_ATTRIBUTE_SSID_NUM
, num_ssid
);
1140 struct nlattr
* attr
= request
.attr_start(EPNO_ATTRIBUTE_SSID_LIST
);
1141 for (int i
= 0; i
< num_ssid
; i
++) {
1142 nlattr
*attr2
= request
.attr_start(i
);
1143 if (attr2
== NULL
) {
1144 return WIFI_ERROR_OUT_OF_MEMORY
;
1146 result
= request
.put(EPNO_ATTRIBUTE_SSID
, ssid_list
[i
].ssid
, 32);
1147 ALOGI("ePNO [SSID:%s rssi_thresh:%d flags:%d auth:%d]", ssid_list
[i
].ssid
,
1148 (signed char)ssid_list
[i
].rssi_threshold
, ssid_list
[i
].flags
,
1149 ssid_list
[i
].auth_bit_field
);
1153 result
= request
.put_u8(EPNO_ATTRIBUTE_SSID_LEN
, strlen(ssid_list
[i
].ssid
));
1158 result
= request
.put_u8(EPNO_ATTRIBUTE_RSSI
, ssid_list
[i
].rssi_threshold
);
1162 result
= request
.put_u8(EPNO_ATTRIBUTE_FLAGS
, ssid_list
[i
].flags
);
1166 result
= request
.put_u8(EPNO_ATTRIBUTE_AUTH
, ssid_list
[i
].auth_bit_field
);
1170 request
.attr_end(attr2
);
1173 request
.attr_end(attr
);
1174 request
.attr_end(data
);
1179 ALOGI("ePNO num_network=%d", num_ssid
);
1180 WifiRequest
request(familyId(), ifaceId());
1181 int result
= createSetupRequest(request
);
1186 result
= requestResponse(request
);
1188 ALOGI("Failed: ePNO setup request, result = %d", result
);
1189 unregisterVendorHandler(GOOGLE_OUI
, WIFI_EPNO_EVENT
);
1193 ALOGI("Successfully set %d SSIDs for ePNO", num_ssid
);
1194 registerVendorHandler(GOOGLE_OUI
, WIFI_EPNO_EVENT
);
1198 virtual int cancel() {
1199 /* unregister event handler */
1200 unregisterVendorHandler(GOOGLE_OUI
, WIFI_EPNO_EVENT
);
1204 virtual int handleResponse(WifiEvent
& reply
) {
1205 /* Nothing to do on response! */
1209 virtual int handleEvent(WifiEvent
& event
) {
1210 ALOGI("ePNO event");
1211 int event_id
= event
.get_vendor_subcmd();
1214 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
1215 int len
= event
.get_vendor_data_len();
1217 if (vendor_data
== NULL
|| len
== 0) {
1218 ALOGI("No scan results found");
1222 mResults
= *(wifi_scan_result
*) event
.get_vendor_data();
1223 if (*mHandler
.on_network_found
)
1224 (*mHandler
.on_network_found
)(id(), 1, &mResults
);
1229 wifi_error
wifi_set_epno_list(wifi_request_id id
,
1230 wifi_interface_handle iface
,
1232 wifi_epno_network
* networks
,
1233 wifi_epno_handler handler
)
1235 wifi_handle handle
= getWifiHandle(iface
);
1237 ePNOCommand
*cmd
= new ePNOCommand(iface
, id
, num_networks
, networks
, handler
);
1238 wifi_register_cmd(handle
, id
, cmd
);
1239 wifi_error result
= (wifi_error
)cmd
->start();
1240 if (result
!= WIFI_SUCCESS
) {
1241 wifi_unregister_cmd(handle
, id
);
1246 class HsListCommand
: public WifiCommand
1249 wifi_passpoint_network
*mNetworks
;
1250 wifi_passpoint_event_handler mHandler
;
1252 HsListCommand(wifi_request_id id
, wifi_interface_handle iface
,
1253 int num
, wifi_passpoint_network
*hs_list
, wifi_passpoint_event_handler handler
)
1254 : WifiCommand(iface
, id
), num_hs(num
), mNetworks(hs_list
),
1259 HsListCommand(wifi_request_id id
, wifi_interface_handle iface
,
1261 : WifiCommand(iface
, id
), num_hs(num
), mNetworks(NULL
)
1265 int createRequest(WifiRequest
& request
, int val
) {
1269 result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_SET_HS_LIST
);
1270 result
= request
.put_u32(EPNO_ATTRIBUTE_HS_NUM
, num_hs
);
1274 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
1276 struct nlattr
* attr
= request
.attr_start(EPNO_ATTRIBUTE_HS_PARAM_LIST
);
1277 for (int i
= 0; i
< num_hs
; i
++) {
1278 nlattr
*attr2
= request
.attr_start(i
);
1279 if (attr2
== NULL
) {
1280 return WIFI_ERROR_OUT_OF_MEMORY
;
1282 result
= request
.put_u32(EPNO_ATTRIBUTE_HS_ID
, mNetworks
[i
].id
);
1286 result
= request
.put(EPNO_ATTRIBUTE_HS_REALM
, mNetworks
[i
].realm
, 256);
1290 result
= request
.put(EPNO_ATTRIBUTE_HS_CONSORTIUM_IDS
, mNetworks
[i
].roamingConsortiumIds
, 128);
1294 result
= request
.put(EPNO_ATTRIBUTE_HS_PLMN
, mNetworks
[i
].plmn
, 3);
1298 request
.attr_end(attr2
);
1300 request
.attr_end(attr
);
1301 request
.attr_end(data
);
1303 result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST
);
1309 return WIFI_SUCCESS
;
1314 WifiRequest
request(familyId(), ifaceId());
1315 int result
= createRequest(request
, num_hs
);
1316 if (result
!= WIFI_SUCCESS
) {
1317 ALOGE("failed to create request; result = %d", result
);
1321 registerVendorHandler(GOOGLE_OUI
, WIFI_HOTSPOT_MATCH
);
1323 result
= requestResponse(request
);
1324 if (result
!= WIFI_SUCCESS
) {
1325 ALOGE("failed to set ANQPO networks; result = %d", result
);
1326 unregisterVendorHandler(GOOGLE_OUI
, WIFI_HOTSPOT_MATCH
);
1333 virtual int cancel() {
1335 WifiRequest
request(familyId(), ifaceId());
1336 int result
= createRequest(request
, 0);
1337 if (result
!= WIFI_SUCCESS
) {
1338 ALOGE("failed to create request; result = %d", result
);
1340 result
= requestResponse(request
);
1341 if (result
!= WIFI_SUCCESS
) {
1342 ALOGE("failed to reset ANQPO networks;result = %d", result
);
1346 unregisterVendorHandler(GOOGLE_OUI
, WIFI_HOTSPOT_MATCH
);
1347 return WIFI_SUCCESS
;
1350 virtual int handleResponse(WifiEvent
& reply
) {
1351 ALOGD("Request complete!");
1352 /* Nothing to do on response! */
1356 virtual int handleEvent(WifiEvent
& event
) {
1358 ALOGI("hotspot matched event");
1359 nlattr
*vendor_data
= event
.get_attribute(NL80211_ATTR_VENDOR_DATA
);
1360 unsigned int len
= event
.get_vendor_data_len();
1361 if (vendor_data
== NULL
|| len
< sizeof(wifi_scan_result
)) {
1362 ALOGE("ERROR: No scan results found");
1366 wifi_scan_result
*result
= (wifi_scan_result
*)event
.get_vendor_data();
1367 byte
*anqp
= (byte
*)result
+ offsetof(wifi_scan_result
, ie_data
) + result
->ie_length
;
1368 int networkId
= *(int *)anqp
;
1369 anqp
+= sizeof(int);
1370 int anqp_len
= *(u16
*)anqp
;
1371 anqp
+= sizeof(u16
);
1373 ALOGI("%-32s\t", result
->ssid
);
1375 ALOGI("%02x:%02x:%02x:%02x:%02x:%02x ", result
->bssid
[0], result
->bssid
[1],
1376 result
->bssid
[2], result
->bssid
[3], result
->bssid
[4], result
->bssid
[5]);
1378 ALOGI("%d\t", result
->rssi
);
1379 ALOGI("%d\t", result
->channel
);
1380 ALOGI("%lld\t", result
->ts
);
1381 ALOGI("%lld\t", result
->rtt
);
1382 ALOGI("%lld\n", result
->rtt_sd
);
1384 if(*mHandler
.on_passpoint_network_found
)
1385 (*mHandler
.on_passpoint_network_found
)(id(), networkId
, result
, anqp_len
, anqp
);
1391 wifi_error
wifi_set_passpoint_list(wifi_request_id id
, wifi_interface_handle iface
, int num
,
1392 wifi_passpoint_network
*networks
, wifi_passpoint_event_handler handler
)
1394 wifi_handle handle
= getWifiHandle(iface
);
1395 HsListCommand
*cmd
= new HsListCommand(id
, iface
, num
, networks
, handler
);
1397 wifi_register_cmd(handle
, id
, cmd
);
1398 wifi_error result
= (wifi_error
)cmd
->start();
1399 if (result
!= WIFI_SUCCESS
) {
1400 wifi_unregister_cmd(handle
, id
);
1405 wifi_error
wifi_reset_passpoint_list(wifi_request_id id
, wifi_interface_handle iface
)
1407 wifi_handle handle
= getWifiHandle(iface
);
1409 HsListCommand
*cmd
= (HsListCommand
*)(wifi_get_cmd(handle
, id
));
1412 cmd
= new HsListCommand(id
, iface
, 0);
1413 wifi_register_cmd(handle
, id
, cmd
);
1415 result
= (wifi_error
)cmd
->cancel();
1416 wifi_unregister_cmd(handle
, id
);
1419 class BssidBlacklistCommand
: public WifiCommand
1422 wifi_bssid_params
*mParams
;
1424 BssidBlacklistCommand(wifi_interface_handle handle
, int id
,
1425 wifi_bssid_params
*params
)
1426 : WifiCommand(handle
, id
), mParams(params
)
1428 int createRequest(WifiRequest
& request
) {
1429 int result
= request
.create(GOOGLE_OUI
, SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_BLACKLIST
);
1434 nlattr
*data
= request
.attr_start(NL80211_ATTR_VENDOR_DATA
);
1435 result
= request
.put_u32(GSCAN_ATTRIBUTE_NUM_BSSID
, mParams
->num_bssid
);
1440 for (int i
= 0; i
< mParams
->num_bssid
; i
++) {
1441 result
= request
.put_addr(GSCAN_ATTRIBUTE_BLACKLIST_BSSID
, mParams
->bssids
[i
]);
1446 request
.attr_end(data
);
1451 ALOGD("Executing bssid blacklist request, num = %d", mParams
->num_bssid
);
1452 WifiRequest
request(familyId(), ifaceId());
1453 int result
= createRequest(request
);
1458 result
= requestResponse(request
);
1460 ALOGE("Failed to execute bssid blacklist request, result = %d", result
);
1464 ALOGI("Successfully added %d blacklist bssids", mParams
->num_bssid
);
1469 virtual int handleResponse(WifiEvent
& reply
) {
1470 /* Nothing to do on response! */
1475 wifi_error
wifi_set_bssid_blacklist(wifi_request_id id
, wifi_interface_handle iface
,
1476 wifi_bssid_params params
)
1478 wifi_handle handle
= getWifiHandle(iface
);
1480 BssidBlacklistCommand
*cmd
= new BssidBlacklistCommand(iface
, id
, ¶ms
);
1481 wifi_error result
= (wifi_error
)cmd
->start();
1482 //release the reference of command as well