Cumulative patch from commit 8b3b803ab9fe69650da7e3b2ee9e44f0f054ee0a
8b3b803 Include Extended Capabilities element based on scan results
6903ee6 P2P Extend postponing of concurrent scans for persistent GO
77e3094 hlr_auc_gw: Fix max_chal value validation
3e6547b hlr_auc_gw: Add support for processing command line operations
2b5b875 EAP-AKA server: Fix AUTS processing
9a50ee6 hlr_auc_gw: Update file comments to mention Milenage
5388dc9 Document use of Linux capabilities instead of privileged process
a771c07 Add driver status information to control interface
739faee nl80211: Add some more debug prints for mgmt frame TX
f78f278 nl80211: Fix off-channel Action frame TX from GO with use_monitor
298f518 Get rid of compiler warning in no-CONFIG_CTRL_IFACE builds
ea61aa1 Add no_ctrl_interface config param to clear ctrl_interface
25b65a1 Make sure updated BSS entry does not get added twice to the list
bbc6c72 P2P: Use group formation timeout on persistent group GO
41f8532 P2P: Extend group formation timeout on GO to first data connection
20625e9 P2P: Remove P2P groups on process termination
76fe79e Register wpa_msg callback even if only global ctrl_iface is used
af96448 nl80211: Add more debug prints for send_mlme operations
5d4c78f nl80211: Reset nlmode to station on leaving IBSS
0249c12 Avoid compiler warning with CONFIG_NO_STDOUT_DEBUG=y
ed1bf01 Allow hostapd config file for dynamically added interface
97bacf7 Do not clear hostapd configuration parameters on disable-iface
66f4dd1 hostapd: Fix couple of deinit path cases to clear pointers
f18b781 nl80211: Print more debug info on management frame RX information
89286e9 Re-open ctrl_iface socket on some failure cases as a workaround
3ca96df atheros: Compile fix for driver code not defining IEEE80211_APPIE_FRAME_WNM
762c92a OpenSSL: Split OCSP peer_cert/peer_issuer debug output into parts
f224cf0 HS 2.0: Allow printf format parsing with language:name strings
913c19c Fix wpa_config_parse_string() to null terminate printf decoded values
04e533e Fix language string length validation in parse_lang_string()
742e715 Simplify ctrl_iface sendto() use
6668efd Clear frequency list on empty value
1a9f247 Make scan_freq field to be saved by save_config
aa78cd3 Drop EAP packet with code 10 before EAPOL state machine processing
3cc247a Use configured sched_scan interval for the PNO scan
d047ae6 WPS: Ignore PBC-to-PIN change from M1 to M2 as a workaround
79986bf Print ctrl_iface sendto() failures into debug log
eab2b50 P2P: Cancel group formation timeout on client connection
00eb299 P2P: Fix operation channel configuration update
Change-Id: I9269e23bc8019b951c2a2d3c707562b2e006148b
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a3ff189..c098150 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -226,6 +226,11 @@
int operstate;
int scan_complete_events;
+ enum scan_states {
+ NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
+ SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
+ SCHED_SCAN_RESULTS
+ } scan_state;
struct nl_cb *nl_cb;
@@ -1520,6 +1525,7 @@
union wpa_event_data event;
u16 fc, stype;
int ssi_signal = 0;
+ int rx_freq = 0;
wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
mgmt = (const struct ieee80211_mgmt *) frame;
@@ -1537,8 +1543,11 @@
os_memset(&event, 0, sizeof(event));
if (freq) {
event.rx_action.freq = nla_get_u32(freq);
- drv->last_mgmt_freq = event.rx_action.freq;
+ rx_freq = drv->last_mgmt_freq = event.rx_action.freq;
}
+ wpa_printf(MSG_DEBUG,
+ "nl80211: RX frame freq=%d ssi_signal=%d stype=%u len=%u",
+ rx_freq, ssi_signal, stype, (unsigned int) len);
if (stype == WLAN_FC_STYPE_ACTION) {
event.rx_action.da = mgmt->da;
event.rx_action.sa = mgmt->sa;
@@ -2578,17 +2587,21 @@
switch (cmd) {
case NL80211_CMD_TRIGGER_SCAN:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
+ drv->scan_state = SCAN_STARTED;
break;
case NL80211_CMD_START_SCHED_SCAN:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
+ drv->scan_state = SCHED_SCAN_STARTED;
break;
case NL80211_CMD_SCHED_SCAN_STOPPED:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
+ drv->scan_state = SCHED_SCAN_STOPPED;
wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
break;
case NL80211_CMD_NEW_SCAN_RESULTS:
wpa_dbg(drv->ctx, MSG_DEBUG,
"nl80211: New scan results available");
+ drv->scan_state = SCAN_COMPLETED;
drv->scan_complete_events = 1;
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
drv->ctx);
@@ -2597,10 +2610,12 @@
case NL80211_CMD_SCHED_SCAN_RESULTS:
wpa_dbg(drv->ctx, MSG_DEBUG,
"nl80211: New sched scan results available");
+ drv->scan_state = SCHED_SCAN_RESULTS;
send_scan_event(drv, 0, tb);
break;
case NL80211_CMD_SCAN_ABORTED:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
+ drv->scan_state = SCAN_ABORTED;
/*
* Need to indicate that scan results are available in order
* not to make wpa_supplicant stop its scanning.
@@ -4381,6 +4396,7 @@
#endif /* HOSTAPD */
}
+ drv->scan_state = SCAN_REQUESTED;
/* Not all drivers generate "scan completed" wireless event, so try to
* read results after a timeout. */
timeout = 10;
@@ -6122,13 +6138,20 @@
struct wpa_driver_nl80211_data *drv = bss->drv;
u64 cookie;
- if (freq == 0)
+ if (freq == 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
+ bss->freq);
freq = bss->freq;
+ }
- if (drv->use_monitor)
+ if (drv->use_monitor) {
+ wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_mntr",
+ freq, bss->freq);
return wpa_driver_nl80211_send_mntr(drv, data, len,
encrypt, noack);
+ }
+ wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
return nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
&cookie, no_cck, noack, offchanok);
}
@@ -6147,6 +6170,8 @@
mgmt = (struct ieee80211_mgmt *) data;
fc = le_to_host16(mgmt->frame_control);
+ wpa_printf(MSG_DEBUG, "nl80211: send_mlme - noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x nlmode=%d",
+ noack, freq, no_cck, offchanok, wait_time, fc, drv->nlmode);
if ((is_sta_interface(drv->nlmode) ||
drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
@@ -6157,16 +6182,22 @@
* but it works due to the single-threaded nature
* of wpa_supplicant.
*/
- if (freq == 0)
+ if (freq == 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
+ drv->last_mgmt_freq);
freq = drv->last_mgmt_freq;
+ }
return nl80211_send_frame_cmd(bss, freq, 0,
data, data_len, NULL, 1, noack,
1);
}
if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
- if (freq == 0)
+ if (freq == 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
+ bss->freq);
freq = bss->freq;
+ }
return nl80211_send_frame_cmd(bss, freq,
(int) freq == bss->freq ? 0 :
wait_time,
@@ -6189,6 +6220,7 @@
encrypt = 0;
}
+ wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
noack, freq, no_cck, offchanok,
wait_time);
@@ -7558,6 +7590,12 @@
wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
nla_put_failure:
+ if (wpa_driver_nl80211_set_mode(&drv->first_bss,
+ NL80211_IFTYPE_STATION)) {
+ wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
+ "station mode");
+ }
+
nlmsg_free(msg);
return ret;
}
@@ -9341,7 +9379,10 @@
os_memcpy(hdr->addr2, src, ETH_ALEN);
os_memcpy(hdr->addr3, bssid, ETH_ALEN);
- if (is_ap_interface(drv->nlmode))
+ if (is_ap_interface(drv->nlmode) &&
+ (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
+ (int) freq == bss->freq || drv->device_ap_sme ||
+ !drv->use_monitor))
ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
0, freq, no_cck, 1,
wait_time);
@@ -10751,6 +10792,163 @@
}
+static const char * scan_state_str(enum scan_states scan_state)
+{
+ switch (scan_state) {
+ case NO_SCAN:
+ return "NO_SCAN";
+ case SCAN_REQUESTED:
+ return "SCAN_REQUESTED";
+ case SCAN_STARTED:
+ return "SCAN_STARTED";
+ case SCAN_COMPLETED:
+ return "SCAN_COMPLETED";
+ case SCAN_ABORTED:
+ return "SCAN_ABORTED";
+ case SCHED_SCAN_STARTED:
+ return "SCHED_SCAN_STARTED";
+ case SCHED_SCAN_STOPPED:
+ return "SCHED_SCAN_STOPPED";
+ case SCHED_SCAN_RESULTS:
+ return "SCHED_SCAN_RESULTS";
+ }
+
+ return "??";
+}
+
+
+static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ int res;
+ char *pos, *end;
+
+ pos = buf;
+ end = buf + buflen;
+
+ res = os_snprintf(pos, end - pos,
+ "ifindex=%d\n"
+ "ifname=%s\n"
+ "brname=%s\n"
+ "addr=" MACSTR "\n"
+ "freq=%d\n"
+ "%s%s%s%s%s",
+ bss->ifindex,
+ bss->ifname,
+ bss->brname,
+ MAC2STR(bss->addr),
+ bss->freq,
+ bss->beacon_set ? "beacon_set=1\n" : "",
+ bss->added_if_into_bridge ?
+ "added_if_into_bridge=1\n" : "",
+ bss->added_bridge ? "added_bridge=1\n" : "",
+ bss->in_deinit ? "in_deinit=1\n" : "",
+ bss->if_dynamic ? "if_dynamic=1\n" : "");
+ if (res < 0 || res >= end - pos)
+ return pos - buf;
+ pos += res;
+
+ if (bss->wdev_id_set) {
+ res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
+ (unsigned long long) bss->wdev_id);
+ if (res < 0 || res >= end - pos)
+ return pos - buf;
+ pos += res;
+ }
+
+ res = os_snprintf(pos, end - pos,
+ "phyname=%s\n"
+ "drv_ifindex=%d\n"
+ "operstate=%d\n"
+ "scan_state=%s\n"
+ "auth_bssid=" MACSTR "\n"
+ "auth_attempt_bssid=" MACSTR "\n"
+ "bssid=" MACSTR "\n"
+ "prev_bssid=" MACSTR "\n"
+ "associated=%d\n"
+ "assoc_freq=%u\n"
+ "monitor_sock=%d\n"
+ "monitor_ifidx=%d\n"
+ "monitor_refcount=%d\n"
+ "last_mgmt_freq=%u\n"
+ "eapol_tx_sock=%d\n"
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ drv->phyname,
+ drv->ifindex,
+ drv->operstate,
+ scan_state_str(drv->scan_state),
+ MAC2STR(drv->auth_bssid),
+ MAC2STR(drv->auth_attempt_bssid),
+ MAC2STR(drv->bssid),
+ MAC2STR(drv->prev_bssid),
+ drv->associated,
+ drv->assoc_freq,
+ drv->monitor_sock,
+ drv->monitor_ifidx,
+ drv->monitor_refcount,
+ drv->last_mgmt_freq,
+ drv->eapol_tx_sock,
+ drv->ignore_if_down_event ?
+ "ignore_if_down_event=1\n" : "",
+ drv->scan_complete_events ?
+ "scan_complete_events=1\n" : "",
+ drv->disabled_11b_rates ?
+ "disabled_11b_rates=1\n" : "",
+ drv->pending_remain_on_chan ?
+ "pending_remain_on_chan=1\n" : "",
+ drv->in_interface_list ? "in_interface_list=1\n" : "",
+ drv->device_ap_sme ? "device_ap_sme=1\n" : "",
+ drv->poll_command_supported ?
+ "poll_command_supported=1\n" : "",
+ drv->data_tx_status ? "data_tx_status=1\n" : "",
+ drv->scan_for_auth ? "scan_for_auth=1\n" : "",
+ drv->retry_auth ? "retry_auth=1\n" : "",
+ drv->use_monitor ? "use_monitor=1\n" : "",
+ drv->ignore_next_local_disconnect ?
+ "ignore_next_local_disconnect=1\n" : "",
+ drv->allow_p2p_device ? "allow_p2p_device=1\n" : "");
+ if (res < 0 || res >= end - pos)
+ return pos - buf;
+ pos += res;
+
+ if (drv->has_capability) {
+ res = os_snprintf(pos, end - pos,
+ "capa.key_mgmt=0x%x\n"
+ "capa.enc=0x%x\n"
+ "capa.auth=0x%x\n"
+ "capa.flags=0x%x\n"
+ "capa.max_scan_ssids=%d\n"
+ "capa.max_sched_scan_ssids=%d\n"
+ "capa.sched_scan_supported=%d\n"
+ "capa.max_match_sets=%d\n"
+ "capa.max_remain_on_chan=%u\n"
+ "capa.max_stations=%u\n"
+ "capa.probe_resp_offloads=0x%x\n"
+ "capa.max_acl_mac_addrs=%u\n"
+ "capa.num_multichan_concurrent=%u\n",
+ drv->capa.key_mgmt,
+ drv->capa.enc,
+ drv->capa.auth,
+ drv->capa.flags,
+ drv->capa.max_scan_ssids,
+ drv->capa.max_sched_scan_ssids,
+ drv->capa.sched_scan_supported,
+ drv->capa.max_match_sets,
+ drv->capa.max_remain_on_chan,
+ drv->capa.max_stations,
+ drv->capa.probe_resp_offloads,
+ drv->capa.max_acl_mac_addrs,
+ drv->capa.num_multichan_concurrent);
+ if (res < 0 || res >= end - pos)
+ return pos - buf;
+ pos += res;
+ }
+
+ return pos - buf;
+}
+
+
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@@ -10832,6 +11030,7 @@
.update_ft_ies = wpa_driver_nl80211_update_ft_ies,
.get_mac_addr = wpa_driver_nl80211_get_macaddr,
.get_survey = wpa_driver_nl80211_get_survey,
+ .status = wpa_driver_nl80211_status,
#ifdef ANDROID_P2P
.set_noa = wpa_driver_set_p2p_noa,
.get_noa = wpa_driver_get_p2p_noa,