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 Oct 7 06:56:52 EDT 2011


Hello Jouni
Could you please let us know your thoughts on implementation of power-save? We see two issues with present implementation. 
1) interval param is not implemented for function p2p_set_noa.
2) After noa attribute or ps mode (ctwindow, legacy_ps) is updated to the driver, p2p_group_notif_noa should get called for updating the P2P IE in beacons.

With the below patch, we have tried to do this way. Please let us know your thoughts on this.

Subject: [PATCH] P2P Adding interval parameter to set_noa and also update beacon after noa params are applied in the driver
---
 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