aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-05-06 04:39:24 -0700
committerLinux Build Service Account <lnxbuild@localhost>2016-05-06 04:39:24 -0700
commita8325dbdadd0095eeb2783d66daae3be1b1e5443 (patch)
treeb3327b1692b78abd0ee615aaff0544ec44bd8d11
parent93d4f498bb3784fcaa522760ea4349252f0c5c5e (diff)
parent425ea41b56ad11cee78cf79ef3971583f95d63cc (diff)
downloadandroid_external_wpa_supplicant_8-a8325dbdadd0095eeb2783d66daae3be1b1e5443.tar.gz
android_external_wpa_supplicant_8-a8325dbdadd0095eeb2783d66daae3be1b1e5443.tar.bz2
android_external_wpa_supplicant_8-a8325dbdadd0095eeb2783d66daae3be1b1e5443.zip
Promotion of wlan-service.lnx.1.0-00045.
CRs Change ID Subject -------------------------------------------------------------------------------------------------------------- 992076 I833a1b9e232485f3a7987ab824b88832cfd0821b eap_proxy: Resolve QMI EAP request length limitation 996616 I5c8ef7e1023e782cd7d18e0294dd3f84564a4c1a WNM: Optimize a single BSS transition management candida 1010891 I6a5cf51cd8b5986078039a4e5ea66dc25fbfa64b WNM: Fetch scan results before checking transition candi 996616 Ia449479732f6a15a78c9aabf821accf201970acf nl80211: Add an option to specify the BSSID to scan for Change-Id: I06a2f58c24f9bc4bfacb8c399443844d47e3b55c CRs-Fixed: 992076, 1010891, 996616
-rw-r--r--src/drivers/driver.h9
-rw-r--r--src/drivers/driver_nl80211_scan.c7
-rw-r--r--src/eap_peer/eap_proxy_qmi.c50
-rw-r--r--wpa_supplicant/scan.c46
-rw-r--r--wpa_supplicant/scan.h5
-rw-r--r--wpa_supplicant/wnm_sta.c169
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
7 files changed, 248 insertions, 39 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 9cea60ca..1abfc1f7 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -416,6 +416,15 @@ struct wpa_driver_scan_params {
*/
const u8 *mac_addr_mask;
+ /**
+ * bssid - Specific BSSID to scan for
+ *
+ * This optional parameter can be used to replace the default wildcard
+ * BSSID with a specific BSSID to scan for if results are needed from
+ * only a single BSS.
+ */
+ const u8 *bssid;
+
/*
* NOTE: Whenever adding new parameters here, please make sure
* wpa_scan_clone_params() and wpa_scan_free_params() get updated with
diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index a8ce7ea8..b84b6449 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -250,6 +250,13 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
goto fail;
}
+ if (params->bssid) {
+ wpa_printf(MSG_DEBUG, "nl80211: Scan for a specific BSSID: "
+ MACSTR, MAC2STR(params->bssid));
+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
+ goto fail;
+ }
+
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
msg = NULL;
if (ret) {
diff --git a/src/eap_peer/eap_proxy_qmi.c b/src/eap_peer/eap_proxy_qmi.c
index 21f6b06d..49ecc4df 100644
--- a/src/eap_peer/eap_proxy_qmi.c
+++ b/src/eap_peer/eap_proxy_qmi.c
@@ -916,7 +916,8 @@ static void handle_qmi_eap_reply(
eap_proxy->qmi_state = QMI_STATE_RESP_TIME_OUT;
return;
}
- if(QMI_AUTH_SEND_EAP_PACKET_REQ_V01 != msg_id)
+ if((QMI_AUTH_SEND_EAP_PACKET_REQ_V01 != msg_id) &&
+ (QMI_AUTH_SEND_EAP_PACKET_EXT_REQ_V01 != msg_id))
{
wpa_printf(MSG_ERROR, "eap_proxy: Invalid msgId =%d\n", msg_id);
eap_proxy->qmi_state = QMI_STATE_RESP_TIME_OUT;
@@ -925,9 +926,10 @@ static void handle_qmi_eap_reply(
/* ensure the reply packet exists */
if (rspData->eap_response_pkt_len <= 0 ||
- rspData->eap_response_pkt_len > QMI_AUTH_EAP_RESP_PACKET_MAX_V01) {
+ rspData->eap_response_pkt_len > QMI_AUTH_EAP_RESP_PACKET_EXT_MAX_V01) {
wpa_printf(MSG_ERROR, "eap_proxy: Reply packet is of"
- "invalid length\n");
+ "invalid length %d error %d result %d\n",
+ rspData->eap_response_pkt_len, rspData->resp.error, rspData->resp.result);
eap_proxy->qmi_state = QMI_STATE_RESP_TIME_OUT;
return;
}
@@ -972,8 +974,9 @@ static enum eap_proxy_status eap_proxy_process(struct eap_proxy_sm *eap_proxy,
auth_send_eap_packet_resp_msg_v01 eap_send_packet_resp;
qmi_txn_handle async_txn_hdl = 0;
- os_memset(&eap_send_packet_req, 0, sizeof(auth_send_eap_packet_req_msg_v01));
- os_memset(&eap_send_packet_resp, 0, sizeof(auth_send_eap_packet_resp_msg_v01));
+ auth_send_eap_packet_ext_req_msg_v01 eap_send_packet_ext_req;
+ auth_send_eap_packet_ext_resp_msg_v01 eap_send_packet_ext_resp;
+
hdr = (struct eap_hdr *)eapReqData;
if ((EAP_CODE_REQUEST == hdr->code) &&
@@ -1005,8 +1008,15 @@ static enum eap_proxy_status eap_proxy_process(struct eap_proxy_sm *eap_proxy,
wpa_printf(MSG_ERROR, "eap_proxy: ***********Dump ReqData len %d***********", eapReqDataLen);
dump_buff(eapReqData, eapReqDataLen);
if (eapReqDataLen <= QMI_AUTH_EAP_REQ_PACKET_MAX_V01) {
+ os_memset(&eap_send_packet_req, 0, sizeof(auth_send_eap_packet_req_msg_v01));
+ os_memset(&eap_send_packet_resp, 0, sizeof(auth_send_eap_packet_resp_msg_v01));
eap_send_packet_req.eap_request_pkt_len = eapReqDataLen ;
memcpy(eap_send_packet_req.eap_request_pkt, eapReqData, eapReqDataLen);
+ } else if (eapReqDataLen <= QMI_AUTH_EAP_REQ_PACKET_EXT_MAX_V01) {
+ os_memset(&eap_send_packet_ext_req, 0, sizeof(auth_send_eap_packet_ext_req_msg_v01));
+ os_memset(&eap_send_packet_ext_resp, 0, sizeof(auth_send_eap_packet_ext_resp_msg_v01));
+ eap_send_packet_ext_req.eap_request_ext_pkt_len = eapReqDataLen;
+ memcpy(eap_send_packet_ext_req.eap_request_ext_pkt, eapReqData, eapReqDataLen);
} else {
wpa_printf(MSG_ERROR, "eap_proxy: Error in eap_send_packet_req\n");
return EAP_PROXY_FAILURE;
@@ -1022,15 +1032,27 @@ static enum eap_proxy_status eap_proxy_process(struct eap_proxy_sm *eap_proxy,
wpa_printf (MSG_ERROR, "eap_proxy: In eap_proxy_process case %d\n", hdr->code);
eap_proxy->qmi_state = QMI_STATE_RESP_PENDING;
- qmiErrorCode = qmi_client_send_msg_async(eap_proxy->qmi_auth_svc_client_ptr[eap_proxy->user_selected_sim],
- QMI_AUTH_SEND_EAP_PACKET_REQ_V01,
- (void *) &eap_send_packet_req,
- sizeof(auth_send_eap_packet_req_msg_v01),
- (void *) &eap_send_packet_resp,
- sizeof(auth_send_eap_packet_resp_msg_v01),
- &handle_qmi_eap_reply, eap_proxy,
- &async_txn_hdl);
-
+ if(eapReqDataLen <= QMI_AUTH_EAP_REQ_PACKET_MAX_V01) {
+ qmiErrorCode = qmi_client_send_msg_async(
+ eap_proxy->qmi_auth_svc_client_ptr[eap_proxy->user_selected_sim],
+ QMI_AUTH_SEND_EAP_PACKET_REQ_V01,
+ (void *) &eap_send_packet_req,
+ sizeof(auth_send_eap_packet_req_msg_v01),
+ (void *) &eap_send_packet_resp,
+ sizeof(auth_send_eap_packet_resp_msg_v01),
+ &handle_qmi_eap_reply, eap_proxy,
+ &async_txn_hdl);
+ } else if(eapReqDataLen <= QMI_AUTH_EAP_REQ_PACKET_EXT_MAX_V01) {
+ qmiErrorCode = qmi_client_send_msg_async(
+ eap_proxy->qmi_auth_svc_client_ptr[eap_proxy->user_selected_sim],
+ QMI_AUTH_SEND_EAP_PACKET_EXT_REQ_V01,
+ (void *) &eap_send_packet_ext_req,
+ sizeof(auth_send_eap_packet_ext_req_msg_v01),
+ (void *) &eap_send_packet_ext_resp,
+ sizeof(auth_send_eap_packet_ext_resp_msg_v01),
+ &handle_qmi_eap_reply, eap_proxy,
+ &async_txn_hdl);
+ }
if (QMI_NO_ERR != qmiErrorCode) {
wpa_printf(MSG_ERROR, "QMI-ERROR Error in sending EAP packet;"
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 93eea4e6..acd3211c 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1013,6 +1013,27 @@ ssid_list_set:
}
}
+ if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
+ struct wpa_bss *bss;
+
+ params.bssid = wpa_s->next_scan_bssid;
+ bss = wpa_bss_get_bssid_latest(wpa_s, params.bssid);
+ if (bss && bss->ssid_len && params.num_ssids == 1 &&
+ params.ssids[0].ssid_len == 0) {
+ params.ssids[0].ssid = bss->ssid;
+ params.ssids[0].ssid_len = bss->ssid_len;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Scan a previously specified BSSID " MACSTR
+ " and SSID %s",
+ MAC2STR(params.bssid),
+ wpa_ssid_txt(bss->ssid, bss->ssid_len));
+ } else {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Scan a previously specified BSSID " MACSTR,
+ MAC2STR(params.bssid));
+ }
+ }
+
scan_params = &params;
scan:
@@ -1073,6 +1094,8 @@ scan:
#ifdef CONFIG_INTERWORKING
wpa_s->interworking_fast_assoc_tried = 0;
#endif /* CONFIG_INTERWORKING */
+ if (params.bssid)
+ os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN);
}
}
@@ -1829,8 +1852,8 @@ int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
}
-static void filter_scan_res(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *res)
+void filter_scan_res(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_results *res)
{
size_t i, j;
@@ -1863,7 +1886,7 @@ static void filter_scan_res(struct wpa_supplicant *wpa_s,
#define DEFAULT_NOISE_FLOOR_2GHZ (-89)
#define DEFAULT_NOISE_FLOOR_5GHZ (-92)
-static void scan_snr(struct wpa_scan_res *res)
+void scan_snr(struct wpa_scan_res *res)
{
if (res->flags & WPA_SCAN_NOISE_INVALID) {
res->noise = IS_5GHZ(res->freq) ?
@@ -1947,8 +1970,8 @@ static unsigned int max_vht80_rate(int snr)
}
-static void scan_est_throughput(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res)
+void scan_est_throughput(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_res *res)
{
enum local_hw_capab capab = wpa_s->hw_capab;
int rate; /* max legacy rate in 500 kb/s units */
@@ -2228,6 +2251,17 @@ wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
params->mac_addr_mask = mac_addr + ETH_ALEN;
}
}
+
+ if (src->bssid) {
+ u8 *bssid;
+
+ bssid = os_malloc(ETH_ALEN);
+ if (!bssid)
+ goto failed;
+ os_memcpy(bssid, src->bssid, ETH_ALEN);
+ params->bssid = bssid;
+ }
+
return params;
failed:
@@ -2255,6 +2289,8 @@ void wpa_scan_free_params(struct wpa_driver_scan_params *params)
*/
os_free((u8 *) params->mac_addr);
+ os_free((u8 *) params->bssid);
+
os_free(params);
}
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 0f1c8e49..893c3c02 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -55,5 +55,10 @@ int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
unsigned int type, const u8 *addr,
const u8 *mask);
int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s);
+void filter_scan_res(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_results *res);
+void scan_snr(struct wpa_scan_res *res);
+void scan_est_throughput(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_res *res);
#endif /* SCAN_H */
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index cec457d1..7a1d3662 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -24,6 +24,7 @@
#define MAX_TFS_IE_LEN 1024
#define WNM_MAX_NEIGHBOR_REPORT 10
+#define WNM_SCAN_RESULT_AGE 2 /* 2 seconds */
/* get the TFS IE from driver */
static int ieee80211_11_get_tfs_ie(struct wpa_supplicant *wpa_s, u8 *buf,
@@ -497,7 +498,7 @@ static void wnm_parse_neighbor_report(struct wpa_supplicant *wpa_s,
static struct wpa_bss *
-compare_scan_neighbor_results(struct wpa_supplicant *wpa_s)
+compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs)
{
u8 i;
@@ -530,6 +531,19 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s)
continue;
}
+ if (age_secs) {
+ struct os_reltime now;
+
+ if (os_get_reltime(&now) == 0 &&
+ os_reltime_expired(&now, &target->last_update,
+ age_secs)) {
+ wpa_printf(MSG_DEBUG,
+ "Candidate BSS is more than %ld seconds old",
+ age_secs);
+ continue;
+ }
+ }
+
if (bss->ssid_len != target->ssid_len ||
os_memcmp(bss->ssid, target->ssid, bss->ssid_len) != 0) {
/*
@@ -622,6 +636,41 @@ static void wnm_send_bss_transition_mgmt_resp(
}
+static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss, struct wpa_ssid *ssid,
+ int after_new_scan)
+{
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WNM: Transition to BSS " MACSTR
+ " based on BSS Transition Management Request (old BSSID "
+ MACSTR " after_new_scan=%d)",
+ MAC2STR(bss->bssid), MAC2STR(wpa_s->bssid), after_new_scan);
+
+ /* Send the BSS Management Response - Accept */
+ if (wpa_s->wnm_reply) {
+ wpa_s->wnm_reply = 0;
+ wpa_printf(MSG_DEBUG,
+ "WNM: Sending successful BSS Transition Management Response");
+ wnm_send_bss_transition_mgmt_resp(wpa_s,
+ wpa_s->wnm_dialog_token,
+ WNM_BSS_TM_ACCEPT,
+ 0, bss->bssid);
+ }
+
+ if (bss == wpa_s->current_bss) {
+ wpa_printf(MSG_DEBUG,
+ "WNM: Already associated with the preferred candidate");
+ wnm_deallocate_memory(wpa_s);
+ return;
+ }
+
+ wpa_s->reassociate = 1;
+ wpa_printf(MSG_DEBUG, "WNM: Issuing connect");
+ wpa_supplicant_connect(wpa_s, bss, ssid);
+ wnm_deallocate_memory(wpa_s);
+}
+
+
int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
{
struct wpa_bss *bss;
@@ -631,6 +680,8 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
if (!wpa_s->wnm_neighbor_report_elements)
return 0;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WNM: Process scan results for BSS Transition Management");
if (os_reltime_before(&wpa_s->wnm_cand_valid_until,
&wpa_s->scan_trigger_time)) {
wpa_printf(MSG_DEBUG, "WNM: Previously stored BSS transition candidate list is not valid anymore - drop it");
@@ -646,7 +697,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
}
/* Compare the Neighbor Report and scan results */
- bss = compare_scan_neighbor_results(wpa_s);
+ bss = compare_scan_neighbor_results(wpa_s, 0);
if (!bss) {
wpa_printf(MSG_DEBUG, "WNM: No BSS transition candidate match found");
status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES;
@@ -654,24 +705,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
}
/* Associate to the network */
- /* Send the BSS Management Response - Accept */
- if (wpa_s->wnm_reply) {
- wpa_s->wnm_reply = 0;
- wnm_send_bss_transition_mgmt_resp(wpa_s,
- wpa_s->wnm_dialog_token,
- WNM_BSS_TM_ACCEPT,
- 0, bss->bssid);
- }
-
- if (bss == wpa_s->current_bss) {
- wpa_printf(MSG_DEBUG,
- "WNM: Already associated with the preferred candidate");
- return 1;
- }
-
- wpa_s->reassociate = 1;
- wpa_supplicant_connect(wpa_s, bss, ssid);
- wnm_deallocate_memory(wpa_s);
+ wnm_bss_tm_connect(wpa_s, bss, ssid, 1);
return 1;
send_bss_resp_fail:
@@ -812,6 +846,79 @@ static void wnm_set_scan_freqs(struct wpa_supplicant *wpa_s)
}
+static int wnm_fetch_scan_results(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_scan_results *scan_res;
+ struct wpa_bss *bss;
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+ u8 i, found = 0;
+ size_t j;
+
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WNM: Fetch current scan results from the driver for checking transition candidates");
+ scan_res = wpa_drv_get_scan_results2(wpa_s);
+ if (!scan_res) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Failed to get scan results");
+ return 0;
+ }
+
+ if (scan_res->fetch_time.sec == 0)
+ os_get_reltime(&scan_res->fetch_time);
+
+ filter_scan_res(wpa_s, scan_res);
+
+ for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
+ struct neighbor_report *nei;
+
+ nei = &wpa_s->wnm_neighbor_report_elements[i];
+ if (nei->preference_present && nei->preference == 0)
+ continue;
+
+ for (j = 0; j < scan_res->num; j++) {
+ struct wpa_scan_res *res;
+ const u8 *ssid_ie;
+
+ res = scan_res->res[j];
+ if (os_memcmp(nei->bssid, res->bssid, ETH_ALEN) != 0 ||
+ res->age > WNM_SCAN_RESULT_AGE * 1000)
+ continue;
+ bss = wpa_s->current_bss;
+ ssid_ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
+ if (bss && ssid_ie &&
+ (bss->ssid_len != ssid_ie[1] ||
+ os_memcmp(bss->ssid, ssid_ie + 2,
+ bss->ssid_len) != 0))
+ continue;
+
+ /* Potential candidate found */
+ found = 1;
+ scan_snr(res);
+ scan_est_throughput(wpa_s, res);
+ wpa_bss_update_scan_res(wpa_s, res,
+ &scan_res->fetch_time);
+ }
+ }
+
+ wpa_scan_results_free(scan_res);
+ if (!found) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WNM: No transition candidate matches existing scan results");
+ return 0;
+ }
+
+ bss = compare_scan_neighbor_results(wpa_s, WNM_SCAN_RESULT_AGE);
+ if (!bss) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WNM: Comparison of scan results against transition candidates did not find matches");
+ return 0;
+ }
+
+ /* Associate to the network */
+ wnm_bss_tm_connect(wpa_s, bss, ssid, 0);
+ return 1;
+}
+
+
static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
const u8 *pos, const u8 *end,
int reply)
@@ -924,6 +1031,20 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
wpa_s->wnm_cand_valid_until.usec %= 1000000;
os_memcpy(wpa_s->wnm_cand_from_bss, wpa_s->bssid, ETH_ALEN);
+ /*
+ * Fetch the latest scan results from the kernel and check for
+ * candidates based on those results first. This can help in
+ * finding more up-to-date information should the driver has
+ * done some internal scanning operations after the last scan
+ * result update in wpa_supplicant.
+ */
+ if (wnm_fetch_scan_results(wpa_s) > 0)
+ return;
+
+ /*
+ * Try to use previously received scan results, if they are
+ * recent enough to use for a connection.
+ */
if (wpa_s->last_scan_res_used > 0) {
struct os_reltime now;
@@ -939,6 +1060,14 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
}
wnm_set_scan_freqs(wpa_s);
+ if (wpa_s->wnm_num_neighbor_report == 1) {
+ os_memcpy(wpa_s->next_scan_bssid,
+ wpa_s->wnm_neighbor_report_elements[0].bssid,
+ ETH_ALEN);
+ wpa_printf(MSG_DEBUG,
+ "WNM: Scan only for a specific BSSID since there is only a single candidate "
+ MACSTR, MAC2STR(wpa_s->next_scan_bssid));
+ }
wpa_supplicant_req_scan(wpa_s, 0, 0);
} else if (reply) {
enum bss_trans_mgmt_status_code status;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 3b7a6994..852f7a6d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -622,6 +622,7 @@ struct wpa_supplicant {
#define MAX_SCAN_ID 16
int scan_id[MAX_SCAN_ID];
unsigned int scan_id_count;
+ u8 next_scan_bssid[ETH_ALEN];
struct wpa_ssid_value *ssids_from_scan_req;
unsigned int num_ssids_from_scan_req;