Cumulative patch from commit 8615bdfac90174c3730ae5e6607b85f8bbec847e
8615bdf Increase global ctrl_iface buffer to same size as per-interface
c5a64e2 GAS client: Use Protected Dual of Public Action frames with PMF
5ce00d0 GAS server: Add support for Protected Dual of Public Action frames
e24fe94 Add definitions for Protected Dual of Public Action frames
7b2c42f hostapd: Fix PMF robust Action frame processing rules
ea6e040 Clear more configuration parameters to default on FLUSH
cf70d29 wpa_supplicant: Schedule PNO on completion of ongoing sched_scan
080cc44 nl80211: Fix sizeof check in vendor command/event handling
a487b35 hostapd: Fix segmentation fault when calling hostapd_cli all_sta
a6cff8b wpa_supplicant: Fix seg fault in wpas_ctrl_radio_work_flush() in error case
f62a3c2 P2P: Clone dtim_period to a new interface
88a0bca Update copyright years in the manpages
32185f5 Sync manpages and command-line options
b948e78 Add manpage for eapol_test
36bd29e wpa_supplicant: Fix usage text based on build options
dcdd383 P2P: Reduce peer expiration age to 60 sec and allow customization
dd27185 Skip normal scan when PNO is already in progress
a2d6365 P2P: Extend the listen time based on the active concurrent session
Change-Id: Iad81dc478319e59d8cfb673e2988d8bd3099b313
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 3fb9e04..8c0cbab 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -86,6 +86,9 @@
{
int len, res, ret, i;
+ if (!sta)
+ return 0;
+
len = 0;
ret = os_snprintf(buf + len, buflen - len, MACSTR "\nflags=",
MAC2STR(sta->addr));
@@ -203,7 +206,11 @@
if (ret < 0 || (size_t) ret >= buflen)
return 0;
return ret;
- }
+ }
+
+ if (!sta->next)
+ return 0;
+
return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
}
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index 8349c4d..b5fb7df 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -1,6 +1,6 @@
/*
* Generic advertisement service (GAS) server
- * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
+ * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -19,6 +19,13 @@
#include "gas_serv.h"
+static void convert_to_protected_dual(struct wpabuf *msg)
+{
+ u8 *categ = wpabuf_mhead_u8(msg);
+ *categ = WLAN_ACTION_PROTECTED_DUAL;
+}
+
+
static struct gas_dialog_info *
gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token)
{
@@ -774,7 +781,7 @@
static void gas_serv_req_local_processing(struct hostapd_data *hapd,
const u8 *sa, u8 dialog_token,
- struct anqp_query_info *qi)
+ struct anqp_query_info *qi, int prot)
{
struct wpabuf *buf, *tx_buf;
@@ -806,6 +813,7 @@
wpabuf_free(buf);
return;
}
+ di->prot = prot;
di->sd_resp = buf;
di->sd_resp_pos = 0;
tx_buf = gas_anqp_build_initial_resp_buf(
@@ -819,7 +827,8 @@
}
if (!tx_buf)
return;
-
+ if (prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
wpabuf_head(tx_buf), wpabuf_len(tx_buf));
wpabuf_free(tx_buf);
@@ -828,7 +837,7 @@
static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
const u8 *sa,
- const u8 *data, size_t len)
+ const u8 *data, size_t len, int prot)
{
const u8 *pos = data;
const u8 *end = data + len;
@@ -878,6 +887,8 @@
return;
wpabuf_put_data(buf, adv_proto, 2 + slen);
wpabuf_put_le16(buf, 0); /* Query Response Length */
+ if (prot)
+ convert_to_protected_dual(buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
wpabuf_head(buf), wpabuf_len(buf));
wpabuf_free(buf);
@@ -929,7 +940,7 @@
pos += elen;
}
- gas_serv_req_local_processing(hapd, sa, dialog_token, &qi);
+ gas_serv_req_local_processing(hapd, sa, dialog_token, &qi, prot);
}
@@ -975,6 +986,8 @@
if (tx_buf) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"GAS: Tx GAS Initial Resp (comeback = 10TU)");
+ if (dialog->prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0,
dst,
wpabuf_head(tx_buf),
@@ -1012,6 +1025,8 @@
dialog->sd_frag_id, (int) frag_len);
dialog->sd_frag_id++;
+ if (dialog->prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, dst,
wpabuf_head(tx_buf), wpabuf_len(tx_buf));
wpabuf_free(tx_buf);
@@ -1022,7 +1037,7 @@
static void gas_serv_rx_gas_comeback_req(struct hostapd_data *hapd,
const u8 *sa,
- const u8 *data, size_t len)
+ const u8 *data, size_t len, int prot)
{
struct gas_dialog_info *dialog;
struct wpabuf *buf, *tx_buf;
@@ -1120,6 +1135,8 @@
}
send_resp:
+ if (prot)
+ convert_to_protected_dual(tx_buf);
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
wpabuf_head(tx_buf), wpabuf_len(tx_buf));
wpabuf_free(tx_buf);
@@ -1137,22 +1154,30 @@
const struct ieee80211_mgmt *mgmt;
size_t hdr_len;
const u8 *sa, *data;
+ int prot;
mgmt = (const struct ieee80211_mgmt *) buf;
hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
if (hdr_len > len)
return;
- if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
+ if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
+ mgmt->u.action.category != WLAN_ACTION_PROTECTED_DUAL)
return;
+ /*
+ * Note: Public Action and Protected Dual of Public Action frames share
+ * the same payload structure, so it is fine to use definitions of
+ * Public Action frames to process both.
+ */
+ prot = mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL;
sa = mgmt->sa;
len -= hdr_len;
data = &mgmt->u.action.u.public_action.action;
switch (data[0]) {
case WLAN_PA_GAS_INITIAL_REQ:
- gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1);
+ gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot);
break;
case WLAN_PA_GAS_COMEBACK_REQ:
- gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1);
+ gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1, prot);
break;
}
}
diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h
index 4213cf6..74739fe 100644
--- a/src/ap/gas_serv.h
+++ b/src/ap/gas_serv.h
@@ -50,6 +50,7 @@
size_t sd_resp_pos; /* Offset in sd_resp */
u8 sd_frag_id;
u16 comeback_delay;
+ int prot; /* whether Protected Dual of Public Action frame is used */
unsigned int requested;
unsigned int received;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 1e3693d..dee3c7a 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1588,8 +1588,8 @@
#ifdef CONFIG_IEEE80211W
if (sta && (sta->flags & WLAN_STA_MFP) &&
- !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
- robust_action_frame(mgmt->u.action.category))) {
+ !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
+ robust_action_frame(mgmt->u.action.category)) {
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"Dropped unprotected Robust Action frame from "
@@ -1619,6 +1619,7 @@
return 1;
#endif /* CONFIG_WNM */
case WLAN_ACTION_PUBLIC:
+ case WLAN_ACTION_PROTECTED_DUAL:
if (hapd->public_action_cb) {
hapd->public_action_cb(hapd->public_action_cb_ctx,
(u8 *) mgmt, len,
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 12dc83e..592ae54 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -271,6 +271,7 @@
#define WLAN_ACTION_FT 6
#define WLAN_ACTION_HT 7
#define WLAN_ACTION_SA_QUERY 8
+#define WLAN_ACTION_PROTECTED_DUAL 9
#define WLAN_ACTION_WNM 10
#define WLAN_ACTION_UNPROTECTED_WNM 11
#define WLAN_ACTION_TDLS 12
@@ -286,6 +287,19 @@
#define WLAN_PA_GAS_COMEBACK_RESP 13
#define WLAN_TDLS_DISCOVERY_RESPONSE 14
+/* Protected Dual of Public Action frames */
+#define WLAN_PROT_DSE_ENABLEMENT 1
+#define WLAN_PROT_DSE_DEENABLEMENT 2
+#define WLAN_PROT_EXT_CSA 4
+#define WLAN_PROT_MEASUREMENT_REQ 5
+#define WLAN_PROT_MEASUREMENT_REPORT 6
+#define WLAN_PROT_DSE_POWER_CONSTRAINT 8
+#define WLAN_PROT_VENDOR_SPECIFIC 9
+#define WLAN_PROT_GAS_INITIAL_REQ 10
+#define WLAN_PROT_GAS_INITIAL_RESP 11
+#define WLAN_PROT_GAS_COMEBACK_REQ 12
+#define WLAN_PROT_GAS_COMEBACK_RESP 13
+
/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */
#define WLAN_SA_QUERY_REQUEST 0
#define WLAN_SA_QUERY_RESPONSE 1
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 0b8eed5..b5bf368 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3584,7 +3584,7 @@
nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
struct nl80211_vendor_cmd_info *vinfo;
- if (nla_len(nl) != sizeof(vinfo)) {
+ if (nla_len(nl) != sizeof(*vinfo)) {
wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
continue;
}
@@ -3600,7 +3600,7 @@
nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
struct nl80211_vendor_cmd_info *vinfo;
- if (nla_len(nl) != sizeof(vinfo)) {
+ if (nla_len(nl) != sizeof(*vinfo)) {
wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
continue;
}
@@ -4216,6 +4216,18 @@
/* GAS Comeback Response */
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
ret = -1;
+ /* Protected GAS Initial Request */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
+ ret = -1;
+ /* Protected GAS Initial Response */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
+ ret = -1;
+ /* Protected GAS Comeback Request */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
+ ret = -1;
+ /* Protected GAS Comeback Response */
+ if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
+ ret = -1;
#endif /* CONFIG_P2P || CONFIG_INTERWORKING */
#ifdef CONFIG_P2P
/* P2P Public Action */
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index f2aa971..8aabfc0 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -43,7 +43,7 @@
*/
#ifndef P2P_PEER_EXPIRATION_AGE
#define P2P_PEER_EXPIRATION_AGE 60
-#endif
+#endif /* P2P_PEER_EXPIRATION_AGE */
#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2)
@@ -3151,13 +3151,13 @@
static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
{
- /*
- * TODO: could remain constantly in Listen state for some time if there
- * are no other concurrent uses for the radio. For now, go to listen
- * state once per second to give other uses a chance to use the radio.
- */
p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
- p2p_set_timeout(p2p, 0, 500000);
+
+ if (p2p->cfg->is_concurrent_session_active &&
+ p2p->cfg->is_concurrent_session_active(p2p->cfg->cb_ctx))
+ p2p_set_timeout(p2p, 0, 500000);
+ else
+ p2p_set_timeout(p2p, 0, 200000);
}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 25a91e7..2ce6ea6 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -789,6 +789,15 @@
*/
void (*presence_resp)(void *ctx, const u8 *src, u8 status,
const u8 *noa, size_t noa_len);
+
+ /**
+ * is_concurrent_session_active - Check whether concurrent session is
+ * active on other virtual interfaces
+ * @ctx: Callback context from cb_ctx
+ * Returns: 1 if concurrent session is active on other virtual interface
+ * or 0 if not.
+ */
+ int (*is_concurrent_session_active)(void *ctx);
};