[PATCH] driver_nl80211: fix mode changes for P2P

Johannes Berg johannes
Wed Jun 22 08:14:15 PDT 2011


From: Johannes Berg <johannes.berg at intel.com>

Recently something has been causing transitions
	GO -> managed -> AP
mode on newly created P2P interfaces, and this
obviously breaks GO mode.

As we discussed this shouldn't be happening,
but it's not clear to me that it won't happen
in the case where P2P doesn't use group iface.

Signed-off-by: Johannes Berg <johannes.berg at intel.com>

--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -186,7 +186,7 @@ struct wpa_driver_nl80211_data {
 
 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
 					    void *timeout_ctx);
-static int wpa_driver_nl80211_set_mode(void *priv, int mode);
+static int wpa_driver_nl80211_set_mode(void *priv, int mode, int p2p);
 static int
 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
@@ -1378,7 +1378,7 @@ static int process_event(struct nl_msg *msg, void *arg)
 	    (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
 	     gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
 		wpa_driver_nl80211_set_mode(&drv->first_bss,
-					    IEEE80211_MODE_AP);
+					    IEEE80211_MODE_AP, 0);
 		drv->ap_scan_as_station = 0;
 	}
 
@@ -2057,7 +2057,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 	drv->first_bss.ifindex = drv->ifindex;
 
 #ifndef HOSTAPD
-	if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA) < 0) {
+	if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA, 0) < 0) {
 		wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
 			   "use managed mode");
 	}
@@ -2184,7 +2184,7 @@ static void wpa_driver_nl80211_deinit(void *priv)
 	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
 
 	(void) linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
-	wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA);
+	wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA, 0);
 
 	if (drv->ioctl_sock >= 0)
 		close(drv->ioctl_sock);
@@ -2219,7 +2219,7 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 	struct wpa_driver_nl80211_data *drv = eloop_ctx;
 	if (drv->ap_scan_as_station) {
 		wpa_driver_nl80211_set_mode(&drv->first_bss,
-					    IEEE80211_MODE_AP);
+					    IEEE80211_MODE_AP, 0);
 		drv->ap_scan_as_station = 0;
 	}
 	wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
@@ -2300,12 +2300,12 @@ static int wpa_driver_nl80211_scan(void *priv,
 			 * try to do this in station mode.
 			 */
 			if (wpa_driver_nl80211_set_mode(bss,
-							IEEE80211_MODE_INFRA))
+							IEEE80211_MODE_INFRA, 0))
 				goto nla_put_failure;
 
 			if (wpa_driver_nl80211_scan(drv, params)) {
 				wpa_driver_nl80211_set_mode(bss,
-							    IEEE80211_MODE_AP);
+							    IEEE80211_MODE_AP, 0);
 				goto nla_put_failure;
 			}
 
@@ -3068,7 +3068,7 @@ static int wpa_driver_nl80211_authenticate(
 	os_memset(drv->auth_bssid, 0, ETH_ALEN);
 	/* FIX: IBSS mode */
 	if (drv->nlmode != NL80211_IFTYPE_STATION &&
-	    wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA) < 0)
+	    wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA, 0) < 0)
 		return -1;
 
 retry:
@@ -4465,7 +4465,8 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
 	if (params->p2p)
 		wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
 			   "group (GO)");
-	if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode) ||
+	if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode,
+					params->p2p) ||
 	    wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
 		nl80211_remove_monitor_interface(drv);
 		return -1;
@@ -4516,7 +4517,7 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
 
 	wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
 
-	if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode)) {
+	if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode, 0)) {
 		wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
 			   "IBSS mode");
 		return -1;
@@ -4757,7 +4758,7 @@ static int wpa_driver_nl80211_associate(
 		return wpa_driver_nl80211_ibss(drv, params);
 
 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
-		if (wpa_driver_nl80211_set_mode(priv, params->mode) < 0)
+		if (wpa_driver_nl80211_set_mode(priv, params->mode, 0) < 0)
 			return -1;
 		return wpa_driver_nl80211_connect(drv, params);
 	}
@@ -4904,7 +4905,7 @@ nla_put_failure:
 }
 
 
-static int wpa_driver_nl80211_set_mode(void *priv, int mode)
+static int wpa_driver_nl80211_set_mode(void *priv, int mode, int p2p)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -4914,13 +4915,13 @@ static int wpa_driver_nl80211_set_mode(void *priv, int mode)
 
 	switch (mode) {
 	case 0:
-		nlmode = NL80211_IFTYPE_STATION;
+		nlmode = p2p ? NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
 		break;
 	case 1:
 		nlmode = NL80211_IFTYPE_ADHOC;
 		break;
 	case 2:
-		nlmode = NL80211_IFTYPE_AP;
+		nlmode = p2p ? NL80211_IFTYPE_P2P_GO : NL80211_IFTYPE_AP;
 		break;
 	default:
 		return -1;
@@ -5739,7 +5740,7 @@ static void *i802_init(struct hostapd_data *hapd,
 			goto failed;
 	}
 
-	if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_AP)) {
+	if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_AP, 0)) {
 		wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
 			   "into AP mode", bss->ifname);
 		goto failed;
@@ -6351,7 +6352,7 @@ static int wpa_driver_nl80211_deinit_ap(void *priv)
 	if (drv->nlmode != NL80211_IFTYPE_AP)
 		return -1;
 	wpa_driver_nl80211_del_beacon(drv);
-	return wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
+	return wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA, 0);
 }
 
 





More information about the Hostap mailing list