aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2010-11-02 17:35:40 (GMT)
committerJouni Malinen <j@w1.fi>2010-11-02 17:35:40 (GMT)
commit534525ff0519076079b85e26192c5b26b6d61381 (patch)
tree68a15e182c159a72d68109079d750526484e576f
parent07fef399a17bfbb52517cc887412177c79c4cfc8 (diff)
downloadhostap-534525ff0519076079b85e26192c5b26b6d61381.zip
hostap-534525ff0519076079b85e26192c5b26b6d61381.tar.gz
hostap-534525ff0519076079b85e26192c5b26b6d61381.tar.bz2
P2P: Skip extra remain-on-channel if oper channel matches
There is no need to separately move to the correct channel for transmitting an Action frame that is using the group interface (i.e., source address is P2P Interface Address). This removes extra latency from P2P Action frame operations within a P2P group.
-rw-r--r--wpa_supplicant/p2p_supplicant.c90
1 files changed, 56 insertions, 34 deletions
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 022ae38..251d00b 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -489,6 +489,35 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
}
+static struct wpa_supplicant *
+wpas_get_tx_interface(struct wpa_supplicant *wpa_s, const u8 *src)
+{
+ struct wpa_supplicant *iface;
+
+ if (os_memcmp(src, wpa_s->own_addr, ETH_ALEN) == 0)
+ return wpa_s;
+
+ /*
+ * Try to find a group interface that matches with the source address.
+ */
+ iface = wpa_s->global->ifaces;
+ while (iface) {
+ if (os_memcmp(wpa_s->pending_action_src,
+ iface->own_addr, ETH_ALEN) == 0)
+ break;
+ iface = iface->next;
+ }
+ if (iface) {
+ wpa_printf(MSG_DEBUG, "P2P: Use group interface %s "
+ "instead of interface %s for Action TX",
+ iface->ifname, wpa_s->ifname);
+ return iface;
+ }
+
+ return wpa_s;
+}
+
+
static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -505,12 +534,26 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
if (wpa_s->pending_action_tx == NULL)
return;
+ /*
+ * This call is likely going to be on the P2P device instance if the
+ * driver uses a separate interface for that purpose. However, some
+ * Action frames are actually sent within a P2P Group and when that is
+ * the case, we need to follow power saving (e.g., GO buffering the
+ * frame for a client in PS mode or a client following the advertised
+ * NoA from its GO). To make that easier for the driver, select the
+ * correct group interface here.
+ */
+ iface = wpas_get_tx_interface(wpa_s, wpa_s->pending_action_src);
+
if (wpa_s->off_channel_freq != wpa_s->pending_action_freq &&
- wpa_s->pending_action_freq != 0) {
+ wpa_s->pending_action_freq != 0 &&
+ wpa_s->pending_action_freq != iface->assoc_freq) {
wpa_printf(MSG_DEBUG, "P2P: Pending Action frame TX "
- "waiting for another freq=%u (off_channel_freq=%u)",
+ "waiting for another freq=%u (off_channel_freq=%u "
+ "assoc_freq=%u)",
wpa_s->pending_action_freq,
- wpa_s->off_channel_freq);
+ wpa_s->off_channel_freq,
+ iface->assoc_freq);
if (without_roc && wpa_s->off_channel_freq == 0) {
/*
* We may get here if wpas_send_action() found us to be
@@ -533,37 +576,6 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
return;
}
- /*
- * This call is likely going to be on the P2P device instance if the
- * driver uses a separate interface for that purpose. However, some
- * Action frames are actually sent within a P2P Group and when that is
- * the case, we need to follow power saving (e.g., GO buffering the
- * frame for a client in PS mode or a client following the advertised
- * NoA from its GO). To make that easier for the driver, select the
- * correct group interface here.
- */
- if (os_memcmp(wpa_s->pending_action_src, wpa_s->own_addr, ETH_ALEN) !=
- 0) {
- /*
- * Try to find a group interface that matches with the source
- * address.
- */
- iface = wpa_s->global->ifaces;
- while (iface) {
- if (os_memcmp(wpa_s->pending_action_src,
- iface->own_addr, ETH_ALEN) == 0)
- break;
- iface = iface->next;
- }
- if (iface) {
- wpa_printf(MSG_DEBUG, "P2P: Use group interface %s "
- "instead of interface %s for Action TX",
- iface->ifname, wpa_s->ifname);
- } else
- iface = wpa_s;
- } else
- iface = wpa_s;
-
wpa_printf(MSG_DEBUG, "P2P: Sending pending Action frame to "
MACSTR " using interface %s",
MAC2STR(wpa_s->pending_action_dst), iface->ifname);
@@ -658,6 +670,16 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN);
wpa_s->pending_action_freq = freq;
+ if (freq) {
+ struct wpa_supplicant *tx_iface;
+ tx_iface = wpas_get_tx_interface(wpa_s, src);
+ if (tx_iface->assoc_freq == freq) {
+ wpa_printf(MSG_DEBUG, "P2P: Already on requested "
+ "channel (TX interface operating channel)");
+ freq = 0;
+ }
+ }
+
if (wpa_s->off_channel_freq == freq || freq == 0) {
wpa_printf(MSG_DEBUG, "P2P: Already on requested channel; "
"send Action frame immediately");