merge in KFS78N (no-op)
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 8740ed5..17fb329 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -416,6 +416,27 @@
}
}
+ /* Prefer a 5 GHz channel */
+ for (i = 0; i < intersection->reg_classes; i++) {
+ struct p2p_reg_class *c = &intersection->reg_class[i];
+ if ((c->reg_class == 115 || c->reg_class == 124) &&
+ c->channels) {
+ unsigned int r;
+
+ /*
+ * Pick one of the available channels in the operating
+ * class at random.
+ */
+ os_get_random((u8 *) &r, sizeof(r));
+ r %= c->channels;
+ p2p_dbg(p2p, "Pick possible 5 GHz channel (op_class %u channel %u) from intersection",
+ c->reg_class, c->channel[r]);
+ p2p->op_reg_class = c->reg_class;
+ p2p->op_channel = c->channel[r];
+ return;
+ }
+ }
+
/*
* Try to see if the original channel is in the intersection. If
* so, no need to change anything, as it already contains some
diff --git a/src/p2p/p2p_utils.c b/src/p2p/p2p_utils.c
index a34c8de..0769ede 100644
--- a/src/p2p/p2p_utils.c
+++ b/src/p2p/p2p_utils.c
@@ -250,7 +250,6 @@
#ifdef ANDROID_P2P
if (freq >= 5170 && freq < 5745)
-
return 0;
#endif
if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0)
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index b7ca075..e911ad0 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -81,6 +81,8 @@
static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs);
static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);
+static void wpa_tdls_disable_peer_link(struct wpa_sm *sm,
+ struct wpa_tdls_peer *peer);
#define TDLS_MAX_IE_LEN 80
@@ -107,6 +109,7 @@
} tpk;
int tpk_set;
int tpk_success;
+ int tpk_in_progress;
struct tpk_timer {
u8 dest[ETH_ALEN];
@@ -276,21 +279,13 @@
static int wpa_tdls_do_teardown(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
- u16 reason_code, int free_peer)
+ u16 reason_code)
{
int ret;
- if (sm->tdls_external_setup) {
- ret = wpa_tdls_send_teardown(sm, peer->addr, reason_code);
-
- /* disable the link after teardown was sent */
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
- } else {
- ret = wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);
- }
-
- if (sm->tdls_external_setup || free_peer)
- wpa_tdls_peer_free(sm, peer);
+ ret = wpa_tdls_send_teardown(sm, peer->addr, reason_code);
+ /* disable the link after teardown was sent */
+ wpa_tdls_disable_peer_link(sm, peer);
return ret;
}
@@ -338,7 +333,7 @@
wpa_printf(MSG_DEBUG, "TDLS: Sending Teardown Request");
wpa_tdls_do_teardown(sm, peer,
- WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
}
}
@@ -616,7 +611,7 @@
wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
" - tear down", MAC2STR(peer->addr));
wpa_tdls_do_teardown(sm, peer,
- WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
}
}
@@ -629,6 +624,7 @@
eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
peer->reconfig_key = 0;
peer->initiator = 0;
+ peer->tpk_in_progress = 0;
os_free(peer->sm_tmr.buf);
peer->sm_tmr.buf = NULL;
os_free(peer->ht_capabilities);
@@ -775,7 +771,15 @@
return -1;
}
- return wpa_tdls_do_teardown(sm, peer, reason_code, 0);
+ return wpa_tdls_do_teardown(sm, peer, reason_code);
+}
+
+
+static void wpa_tdls_disable_peer_link(struct wpa_sm *sm,
+ struct wpa_tdls_peer *peer)
+{
+ wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
+ wpa_tdls_peer_free(sm, peer);
}
@@ -788,10 +792,8 @@
break;
}
- if (peer) {
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
- wpa_tdls_peer_free(sm, peer);
- }
+ if (peer)
+ wpa_tdls_disable_peer_link(sm, peer);
}
@@ -864,11 +866,7 @@
* Request the driver to disable the direct link and clear associated
* keys.
*/
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
-
- /* clear the Peerkey statemachine */
- wpa_tdls_peer_free(sm, peer);
-
+ wpa_tdls_disable_peer_link(sm, peer);
return 0;
}
@@ -1483,19 +1481,7 @@
wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
"direct link is enabled - tear down the "
"old link first");
-#if 0
- /* TODO: Disabling the link would be more proper
- * operation here, but it seems to trigger a race with
- * some drivers handling the new request frame. */
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
-#else
- if (sm->tdls_external_setup)
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
- src_addr);
- else
- wpa_tdls_del_key(sm, peer);
-#endif
- wpa_tdls_peer_free(sm, peer);
+ wpa_tdls_disable_peer_link(sm, peer);
}
/*
@@ -1516,12 +1502,7 @@
MACSTR " (terminate previously "
"initiated negotiation",
MAC2STR(src_addr));
- if (sm->tdls_external_setup)
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
- src_addr);
- else
- wpa_tdls_del_key(sm, peer);
- wpa_tdls_peer_free(sm, peer);
+ wpa_tdls_disable_peer_link(sm, peer);
}
}
}
@@ -1683,16 +1664,27 @@
}
ftie = (struct wpa_tdls_ftie *) kde.ftie;
- os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
peer->rsnie_i_len = kde.rsn_ie_len;
peer->cipher = cipher;
- if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
- wpa_msg(sm->ctx->ctx, MSG_WARNING,
- "TDLS: Failed to get random data for responder nonce");
- wpa_tdls_peer_free(sm, peer);
- goto error;
+ if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) {
+ /*
+ * There is no point in updating the RNonce for every obtained
+ * TPK M1 frame (e.g., retransmission due to timeout) with the
+ * same INonce (SNonce in FTIE). However, if the TPK M1 is
+ * retransmitted with a different INonce, update the RNonce
+ * since this is for a new TDLS session.
+ */
+ wpa_printf(MSG_DEBUG,
+ "TDLS: New TPK M1 INonce - generate new RNonce");
+ os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
+ if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
+ wpa_msg(sm->ctx->ctx, MSG_WARNING,
+ "TDLS: Failed to get random data for responder nonce");
+ wpa_tdls_peer_free(sm, peer);
+ goto error;
+ }
}
#if 0
@@ -1748,10 +1740,11 @@
/* add the peer to the driver as a "setup in progress" peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
NULL, 0);
+ peer->tpk_in_progress = 1;
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
- wpa_tdls_disable_link(sm, peer->addr);
+ wpa_tdls_disable_peer_link(sm, peer);
goto error;
}
@@ -1767,6 +1760,7 @@
static int wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
peer->tpk_success = 1;
+ peer->tpk_in_progress = 0;
eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
if (wpa_tdls_get_privacy(sm)) {
u32 lifetime = peer->lifetime;
@@ -1848,8 +1842,11 @@
}
wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
- if (len < 3 + 2 + 1)
+ if (len < 3 + 2 + 1) {
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
+ }
+
pos = buf;
pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
status = WPA_GET_LE16(pos);
@@ -1858,8 +1855,7 @@
if (status != WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
status);
- if (sm->tdls_external_setup)
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
}
@@ -1870,8 +1866,10 @@
wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);
- if (len < 3 + 2 + 1 + 2)
+ if (len < 3 + 2 + 1 + 2) {
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
+ }
/* capability information */
peer->capability = WPA_GET_LE16(pos);
@@ -2012,9 +2010,7 @@
(u8 *) timeoutie, ftie) < 0) {
/* Discard the frame */
wpa_tdls_del_key(sm, peer);
- wpa_tdls_peer_free(sm, peer);
- if (sm->tdls_external_setup)
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
}
@@ -2034,7 +2030,7 @@
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
"TPK Handshake Message 3");
if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0) {
- wpa_tdls_disable_link(sm, peer->addr);
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
}
@@ -2042,14 +2038,14 @@
if (ret < 0) {
wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
wpa_tdls_do_teardown(sm, peer,
- WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
}
return ret;
error:
wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
status);
- wpa_tdls_disable_link(sm, peer->addr);
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
}
@@ -2082,7 +2078,7 @@
wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);
if (len < 3 + 3)
- return -1;
+ goto error;
pos = buf;
pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
@@ -2091,21 +2087,19 @@
if (status != 0) {
wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
status);
- if (sm->tdls_external_setup)
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
- return -1;
+ goto error;
}
pos += 2 /* status code */ + 1 /* dialog token */;
ielen = len - (pos - buf); /* start of IE in buf */
if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
wpa_printf(MSG_INFO, "TDLS: Failed to parse KDEs in TPK M3");
- return -1;
+ goto error;
}
if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
- return -1;
+ goto error;
}
wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
(u8 *) kde.lnkid, kde.lnkid_len);
@@ -2113,7 +2107,7 @@
if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
- return -1;
+ goto error;
}
if (!wpa_tdls_get_privacy(sm))
@@ -2121,7 +2115,7 @@
if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
- return -1;
+ goto error;
}
wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
kde.ftie, sizeof(*ftie));
@@ -2129,7 +2123,7 @@
if (kde.rsn_ie == NULL) {
wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
- return -1;
+ goto error;
}
wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
kde.rsn_ie, kde.rsn_ie_len);
@@ -2137,24 +2131,24 @@
os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
"with the one sent in TPK M2");
- return -1;
+ goto error;
}
if (!os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) == 0) {
wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
"not match with FTIE ANonce used in TPK M2");
- return -1;
+ goto error;
}
if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
"match with FTIE SNonce used in TPK M1");
- return -1;
+ goto error;
}
if (kde.key_lifetime == NULL) {
wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
- return -1;
+ goto error;
}
timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
@@ -2165,16 +2159,13 @@
if (lifetime != peer->lifetime) {
wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
"TPK M3 (expected %u)", lifetime, peer->lifetime);
- if (sm->tdls_external_setup)
- wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
- return -1;
+ goto error;
}
if (wpa_supplicant_verify_tdls_mic(3, peer, (u8 *) lnkid,
(u8 *) timeoutie, ftie) < 0) {
wpa_tdls_del_key(sm, peer);
- wpa_tdls_peer_free(sm, peer);
- return -1;
+ goto error;
}
if (wpa_tdls_set_key(sm, peer) < 0) {
@@ -2192,9 +2183,12 @@
if (ret < 0) {
wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
wpa_tdls_do_teardown(sm, peer,
- WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
}
return ret;
+error:
+ wpa_tdls_disable_peer_link(sm, peer);
+ return -1;
}
@@ -2248,14 +2242,21 @@
if (peer == NULL)
return -1;
+ if (peer->tpk_in_progress) {
+ wpa_printf(MSG_DEBUG, "TDLS: Setup is already in progress with the peer");
+ return 0;
+ }
+
peer->initiator = 1;
/* add the peer to the driver as a "setup in progress" peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
NULL, 0);
+ peer->tpk_in_progress = 1;
+
if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
- wpa_tdls_disable_link(sm, peer->addr);
+ wpa_tdls_disable_peer_link(sm, peer);
return -1;
}
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 0e1576b..67a9f97 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -343,6 +343,14 @@
os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len);
wpa_bss_set_hessid(bss);
+ if (wpa_s->num_bss + 1 > wpa_s->conf->bss_max_count &&
+ wpa_bss_remove_oldest(wpa_s) != 0) {
+ wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
+ "because all BSSes are in use. We should normally "
+ "not get here!", (int) wpa_s->num_bss + 1);
+ wpa_s->conf->bss_max_count = wpa_s->num_bss + 1;
+ }
+
dl_list_add_tail(&wpa_s->bss, &bss->list);
dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
wpa_s->num_bss++;
@@ -350,13 +358,6 @@
" SSID '%s'",
bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
- if (wpa_s->num_bss > wpa_s->conf->bss_max_count &&
- wpa_bss_remove_oldest(wpa_s) != 0) {
- wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
- "because all BSSes are in use. We should normally "
- "not get here!", (int) wpa_s->num_bss);
- wpa_s->conf->bss_max_count = wpa_s->num_bss;
- }
return bss;
}
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 8736b07..af57afa 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5150,8 +5150,19 @@
int ret;
ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
- if (ret == 0)
+ if (ret == 0) {
+ if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
+ struct p2p_data *p2p = wpa_s->global->p2p;
+ if (p2p) {
+ char country[3];
+ country[0] = cmd[8];
+ country[1] = cmd[9];
+ country[2] = 0x04;
+ p2p_set_country(p2p, country);
+ }
+ }
ret = sprintf(buf, "%s\n", "OK");
+ }
return ret;
}
#endif
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8c29b20..9de8d7f 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2292,8 +2292,12 @@
wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer);
break;
case TDLS_REQUEST_TEARDOWN:
- wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
- data->tdls.reason_code);
+ if (wpa_tdls_is_external_setup(wpa_s->wpa))
+ wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
+ data->tdls.reason_code);
+ else
+ wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN,
+ data->tdls.peer);
break;
}
}