[PATCH] P2P Adding interval parameter to set_noa and also update beacon after noa params are applied in the driver

Neeraj Kumar Garg neerajkg at broadcom.com
Fri Sep 30 09:54:58 EDT 2011


p2p_set noa doesn't support interval parameter. This paramter is essential for setting up presence of GO between the time of (interval - duration). This is also required by WifiDirect Sigma Test-suite for optional tests.
Also we need to update the beacon information after setting the NOA in the driver.
Also when overwriting group->noa in p2p_group.c, we need to put group->noa_used=0 otherwise, wpa_buf_put_data will crash when p2p_group_notif_noa is called again.
Also we need to update becaon (p2p_group_notif_noa) for opportunistic power-save.

---
 src/ap/ap_drv_ops.c             |    4 +-
 src/ap/ap_drv_ops.h             |    2 +-
 src/ap/hostapd.h                |    1 +
 src/ap/p2p_hostapd.c            |   14 ++++++------
 src/ap/p2p_hostapd.h            |    2 +-
 src/drivers/driver.h            |    2 +-
 src/p2p/p2p_group.c             |    4 +-
 wpa_supplicant/ctrl_iface.c     |   22 +++++++++++++-------
 wpa_supplicant/p2p_supplicant.c |   42 +++++++++++++++++++++++++++++++++++---
 wpa_supplicant/p2p_supplicant.h |    4 ++-
 10 files changed, 70 insertions(+), 27 deletions(-)
 mode change 100644 => 100755 src/ap/ap_drv_ops.c
 mode change 100644 => 100755 src/ap/ap_drv_ops.h
 mode change 100644 => 100755 src/ap/hostapd.h
 mode change 100644 => 100755 src/ap/p2p_hostapd.c
 mode change 100644 => 100755 src/ap/p2p_hostapd.h
 mode change 100644 => 100755 src/drivers/driver.h
 mode change 100644 => 100755 src/p2p/p2p_group.c
 mode change 100644 => 100755 wpa_supplicant/ctrl_iface.c
 mode change 100644 => 100755 wpa_supplicant/p2p_supplicant.c
 mode change 100644 => 100755 wpa_supplicant/p2p_supplicant.h

diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
old mode 100644
new mode 100755
index 9751b29..a45a2c3
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -643,11 +643,11 @@ struct wpa_scan_results * hostapd_driver_get_scan_results(
 
 
 int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
-			   int duration)
+			   int duration, int interval)
 {
 	if (hapd->driver && hapd->driver->set_noa)
 		return hapd->driver->set_noa(hapd->drv_priv, count, start,
-					     duration);
+					     duration, interval);
 	return -1;
 }
 
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
old mode 100644
new mode 100755
index f270695..260fc50
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -90,7 +90,7 @@ int hostapd_driver_scan(struct hostapd_data *hapd,
 struct wpa_scan_results * hostapd_driver_get_scan_results(
 	struct hostapd_data *hapd);
 int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
-			   int duration);
+			   int duration, int interval);
 int hostapd_drv_set_key(const char *ifname,
 			struct hostapd_data *hapd,
 			enum wpa_alg alg, const u8 *addr,
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
old mode 100644
new mode 100755
index 803776c..a49ad71
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -163,6 +163,7 @@ struct hostapd_data {
 	int noa_enabled;
 	int noa_start;
 	int noa_duration;
+	int noa_interval;
 #endif /* CONFIG_P2P */
 };
 
diff --git a/src/ap/p2p_hostapd.c b/src/ap/p2p_hostapd.c
old mode 100644
new mode 100755
index 6f8b778..f1af146
--- a/src/ap/p2p_hostapd.c
+++ b/src/ap/p2p_hostapd.c
@@ -35,9 +35,8 @@ int hostapd_p2p_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
 	return p2p_ie_text(sta->p2p_ie, buf, buf + buflen);
 }
 
-
 int hostapd_p2p_set_noa(struct hostapd_data *hapd, u8 count, int start,
-			int duration)
+			int duration, int interval)
 {
 	wpa_printf(MSG_DEBUG, "P2P: Set NoA parameters: count=%u start=%d "
 		   "duration=%d", count, start, duration);
@@ -46,22 +45,23 @@ int hostapd_p2p_set_noa(struct hostapd_data *hapd, u8 count, int start,
 		hapd->noa_enabled = 0;
 		hapd->noa_start = 0;
 		hapd->noa_duration = 0;
+		hapd->noa_interval = 0;
 	}
 
 	if (count != 255) {
 		wpa_printf(MSG_DEBUG, "P2P: Non-periodic NoA - set "
 			   "NoA parameters");
-		return hostapd_driver_set_noa(hapd, count, start, duration);
+		return hostapd_driver_set_noa(hapd, count, start, duration, interval);
 	}
 
 	hapd->noa_enabled = 1;
 	hapd->noa_start = start;
 	hapd->noa_duration = duration;
-
+	hapd->noa_interval = interval;
 	if (hapd->num_sta_no_p2p == 0) {
 		wpa_printf(MSG_DEBUG, "P2P: No legacy STAs connected - update "
 			   "periodic NoA parameters");
-		return hostapd_driver_set_noa(hapd, count, start, duration);
+		return hostapd_driver_set_noa(hapd, count, start, duration, interval);
 	}
 
 	wpa_printf(MSG_DEBUG, "P2P: Legacy STA(s) connected - do not enable "
@@ -77,7 +77,7 @@ void hostapd_p2p_non_p2p_sta_connected(struct hostapd_data *hapd)
 
 	if (hapd->noa_enabled) {
 		wpa_printf(MSG_DEBUG, "P2P: Disable periodic NoA");
-		hostapd_driver_set_noa(hapd, 0, 0, 0);
+		hostapd_driver_set_noa(hapd, 0, 0, 0, 0);
 	}
 }
 
@@ -89,7 +89,7 @@ void hostapd_p2p_non_p2p_sta_disconnected(struct hostapd_data *hapd)
 	if (hapd->noa_enabled) {
 		wpa_printf(MSG_DEBUG, "P2P: Enable periodic NoA");
 		hostapd_driver_set_noa(hapd, 255, hapd->noa_start,
-				       hapd->noa_duration);
+				       hapd->noa_duration, hapd->noa_interval);
 	}
 }
 
diff --git a/src/ap/p2p_hostapd.h b/src/ap/p2p_hostapd.h
old mode 100644
new mode 100755
index 95b31d9..779c4a4
--- a/src/ap/p2p_hostapd.h
+++ b/src/ap/p2p_hostapd.h
@@ -20,7 +20,7 @@
 int hostapd_p2p_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
 			    char *buf, size_t buflen);
 int hostapd_p2p_set_noa(struct hostapd_data *hapd, u8 count, int start,
-			int duration);
+			int duration, int interval);
 void hostapd_p2p_non_p2p_sta_connected(struct hostapd_data *hapd);
 void hostapd_p2p_non_p2p_sta_disconnected(struct hostapd_data *hapd);
 
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
old mode 100644
new mode 100755
index f51df4e..fd94c97
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2090,7 +2090,7 @@ struct wpa_driver_ops {
 	 * is used only for testing. To disable NoA, all parameters are set to
 	 * 0.
 	 */
-	int (*set_noa)(void *priv, u8 count, int start, int duration);
+	int (*set_noa)(void *priv, u8 count, int start, int duration, int interval);
 
 	/**
 	 * set_p2p_powersave - Set P2P power save options
diff --git a/src/p2p/p2p_group.c b/src/p2p/p2p_group.c
old mode 100644
new mode 100755
index 14a475d..b6323b2
--- a/src/p2p/p2p_group.c
+++ b/src/p2p/p2p_group.c
@@ -494,7 +494,7 @@ int p2p_group_notif_noa(struct p2p_group *group, const u8 *noa,
 	} else {
 		if (group->noa) {
 			if (wpabuf_size(group->noa) >= noa_len) {
-				group->noa->size = 0;
+				group->noa->used = 0;
 				wpabuf_put_data(group->noa, noa, noa_len);
 			} else {
 				wpabuf_free(group->noa);
@@ -642,7 +642,7 @@ u8 p2p_group_presence_req(struct p2p_group *group,
 			    curr_noa_len);
 
 	/* TODO: properly process request and store copy */
-	if (curr_noa_len > 0)
+	if (curr_noa_len < 0)
 		return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
 
 	return P2P_SC_SUCCESS;
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
old mode 100644
new mode 100755
index a55a528..72520c8
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2709,10 +2709,9 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
 		return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
 					    os_strlen(param));
 	}
-
 	if (os_strcmp(cmd, "noa") == 0) {
 		char *pos;
-		int count, start, duration;
+		int count, start, duration, interval;
 		/* GO NoA parameters: count,start_offset(ms),duration(ms) */
 		count = atoi(param);
 		pos = os_strchr(param, ',');
@@ -2725,23 +2724,30 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
 			return -1;
 		pos++;
 		duration = atoi(pos);
-		if (count < 0 || count > 255 || start < 0 || duration < 0)
+		pos = os_strchr(pos, ',');
+		if (pos == NULL)
+			return -1;
+		pos++;
+		interval = atoi(pos);
+		if (count < 0 || count > 255 || start < 0 || duration < 0 || interval < 0 || interval < duration)
 			return -1;
 		if (count == 0 && duration > 0)
 			return -1;
+		if (count == 0 && interval > 0)
+			return -1;
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
-			   "start=%d duration=%d", count, start, duration);
-		return wpas_p2p_set_noa(wpa_s, count, start, duration);
+			   "start=%d duration=%d interval=%d", count, start, duration, interval);
+		return wpas_p2p_set_noa(wpa_s, count, start, duration, interval);
 	}
 
 	if (os_strcmp(cmd, "ps") == 0)
-		return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
+		return wpas_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
 
 	if (os_strcmp(cmd, "oppps") == 0)
-		return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
+		return wpas_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
 
 	if (os_strcmp(cmd, "ctwindow") == 0)
-		return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
+		return wpas_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
 
 	if (os_strcmp(cmd, "disabled") == 0) {
 		wpa_s->global->p2p_disabled = atoi(param);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
old mode 100644
new mode 100755
index 92bfc41..6c10d1a
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3863,14 +3863,48 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
 	}
 }
 
-
+#define NOA_BUF_LEN 50
 int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
-		     int duration)
+		     int duration, int interval)
 {
 	if (!wpa_s->ap_iface)
 		return -1;
-	return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
-				   duration);
+	/* Set the NOA descriptor in the driver */
+	if (hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
+			duration, interval) < 0) {
+		wpa_printf(MSG_ERROR, "P2P: Set NOA attributes in driver failed");
+		return -1;
+	}
+
+	if(count > 0) {
+		u8 noa[NOA_BUF_LEN];
+		int noa_len = 0;
+		wpa_printf(MSG_DEBUG, "P2P: Get NOA attribute from driver");
+		noa_len = wpa_drv_get_noa(wpa_s, noa, NOA_BUF_LEN);
+		if (noa_len) {
+			wpa_printf(MSG_DEBUG, "P2P: Update NOA attributes in Beacons/ProbeRsps noa_len %d", noa_len);
+			return p2p_group_notif_noa(wpa_s->p2p_group, noa, noa_len);
+		}
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+int wpas_drv_set_p2p_powersave(struct wpa_supplicant *wpa_s, int legacy_ps, int opp_ps, int ctwindow)
+{
+
+	u8 noa[NOA_BUF_LEN];
+	int noa_len = 0;
+	wpa_drv_set_p2p_powersave(wpa_s, legacy_ps, opp_ps, ctwindow);
+	wpa_printf(MSG_DEBUG, "P2P: Get NOA attribute from driver");
+	noa_len = wpa_drv_get_noa(wpa_s, noa, NOA_BUF_LEN);
+	if (noa_len) {
+		wpa_printf(MSG_DEBUG, "P2P: Now Update NOA attributes in Beacons/ProbeRsps noa_len %d", noa_len);
+		return p2p_group_notif_noa(wpa_s->p2p_group, noa, noa_len);
+	}
+	else
+		return 0;
 }
 
 
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
old mode 100644
new mode 100755
index 9a13f9f..71a8839
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -109,11 +109,13 @@ int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
 			unsigned int interval);
 void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
 			   u16 reason_code, const u8 *ie, size_t ie_len);
+int wpas_drv_set_p2p_powersave(struct wpa_supplicant *wpa_s, int legacy_ps,
+	int opp_ps, int ctwindow);
 void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
 			     u16 reason_code, const u8 *ie, size_t ie_len);
 void wpas_p2p_update_config(struct wpa_supplicant *wpa_s);
 int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
-		     int duration);
+		     int duration, int interval);
 int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled);
 void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s);
 void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s);
-- 
1.7.4.1
 
Regards,
-Neeraj



More information about the HostAP mailing list