[PATCH] supplicant: add dbus getter method for nl80211 iftype

Avinash Patil avinashapatil at gmail.com
Thu Dec 4 13:00:17 EST 2014


From: Avinash Patil <patila at marvell.com>

This patch adds dbus getter method for nl80211 iftype.
This is required by certain applications which intend to start
AP operations only if current interface type is AP.
Getter method for capabilities cannot be used for this purpose as
this enumarates all the supported interface types.

Patch also adds notification handlers for interface type change
events.

Signed-off-by: Avinash Patil <patila at marvell.com>
Signed-off-by: Avinash Patil <avinashapatil at gmail.com>
---
 src/drivers/driver.h                    | 13 ++++++++++++
 src/drivers/driver_nl80211.c            | 16 ++++++++++++++
 wpa_supplicant/dbus/dbus_new.c          | 17 +++++++++++++++
 wpa_supplicant/dbus/dbus_new.h          |  6 ++++++
 wpa_supplicant/dbus/dbus_new_handlers.c | 37 +++++++++++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  3 +++
 wpa_supplicant/driver_i.h               | 10 +++++++++
 wpa_supplicant/events.c                 | 14 +++++++++++++
 wpa_supplicant/notify.c                 |  4 ++++
 wpa_supplicant/notify.h                 |  1 +
 wpa_supplicant/p2p_supplicant.c         | 13 ++++++++++++
 wpa_supplicant/wpa_supplicant.c         | 28 +++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h       |  1 +
 13 files changed, 163 insertions(+)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 05f6a05..af50dbc 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1199,6 +1199,7 @@ struct hostapd_acl_params {
 	struct mac_address mac_acl[0];
 };
 
+#define IFTYPE_SZ 20
 enum wpa_driver_if_type {
 	/**
 	 * WPA_IF_STATION - Station mode interface
@@ -1472,6 +1473,18 @@ struct wpa_driver_ops {
 	int (*get_ssid)(void *priv, u8 *ssid);
 
 	/**
+	 * get_iftype - Get the current iftype
+	 * @priv: private driver interface data
+	 * @iftype: buffer for storing iftype
+	 *
+	 * Returns: 0 on success, -1 on failure
+	 *
+	 * Query kernel driver for the current mode and copy it to
+	 * iftype.
+	 */
+	int (*get_iftype)(void *priv, char *iftype);
+
+	/**
 	 * set_key - Configure encryption key
 	 * @ifname: Interface name (for multi-SSID/VLAN support)
 	 * @priv: private driver interface data
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 2b4abf3..14a5cf1 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -185,6 +185,7 @@ static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
 
 static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
 static int i802_set_iface_flags(struct i802_bss *bss, int up);
+static const char *nl80211_iftype_str(enum nl80211_iftype mode);
 
 
 /* Converts nl80211_chan_width to a common format */
@@ -737,6 +738,20 @@ static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
 	return 0;
 }
 
+static int
+wpa_driver_nl80211_get_nl80211_iftype(void *priv, char *iftype_str)
+{
+	int iftype;
+	struct i802_bss *bss = priv;
+
+	if (!bss)
+		return -1;
+
+	iftype = (u8)nl80211_get_ifmode(bss);
+	strcpy(iftype_str, nl80211_iftype_str(iftype));
+
+	return 0;
+}
 
 static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
 {
@@ -9246,6 +9261,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.desc = "Linux nl80211/cfg80211",
 	.get_bssid = wpa_driver_nl80211_get_bssid,
 	.get_ssid = wpa_driver_nl80211_get_ssid,
+	.get_iftype = wpa_driver_nl80211_get_nl80211_iftype,
 	.set_key = driver_nl80211_set_key,
 	.scan2 = driver_nl80211_scan2,
 	.sched_scan = wpa_driver_nl80211_sched_scan,
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index cbf9d32..12a059b 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2037,6 +2037,19 @@ void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
 
 
 /**
+ * wpas_dbus_signal_interface_type_changed - Signals change of interface type
+ * @global: wpa_global structure
+ *
+ * Sends PropertyChanged signals informing that debug level has changed.
+ */
+void wpas_dbus_signal_interface_type_changed(struct wpa_global *global)
+{
+	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
+				       WPAS_DBUS_NEW_INTERFACE,
+				       "IfType");
+}
+
+/**
  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
  * @global: wpa_global structure
  *
@@ -2956,6 +2969,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
 	  wpas_dbus_getter_driver,
 	  NULL
 	},
+	{ "IfType", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
+	  wpas_dbus_getter_iftype,
+	  NULL
+	},
 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
 	  wpas_dbus_getter_bridge_ifname,
 	  NULL
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 5f32bbf..dcb444f 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -164,6 +164,7 @@ void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
 				   const char *name);
 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global);
+void wpas_dbus_signal_interface_type_changed(struct wpa_global *global);
 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global);
 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global);
 
@@ -332,6 +333,11 @@ static inline void wpas_dbus_signal_debug_level_changed(
 {
 }
 
+static inline void wpas_dbus_signal_interface_type_changed(
+	struct wpa_global *global)
+{
+}
+
 static inline void wpas_dbus_signal_debug_timestamp_changed(
 	struct wpa_global *global)
 {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index eefc15d..46af85e 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3166,6 +3166,43 @@ dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
 						&driver, error);
 }
 
+/**
+ * wpas_dbus_getter_iftype -
+ * Get current interface type
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Getter for  "IfType" property.
+ */
+dbus_bool_t wpas_dbus_getter_iftype(DBusMessageIter *iter, DBusError *error,
+				    void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	char char_iftype[IFTYPE_SZ];
+	const char *iftype = char_iftype;
+
+	if (wpa_s->driver == NULL) {
+		wpa_printf(MSG_DEBUG, "wpas_dbus_getter_iftype[dbus]: "
+			   "wpa_s has no driver set");
+		dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set",
+			       __func__);
+		return FALSE;
+	}
+
+	if (wpa_drv_get_iftype(wpa_s, char_iftype)) {
+		wpa_printf(MSG_DEBUG, "wpas_dbus_getter_iftype[dbus]: "
+			   "failed");
+		dbus_set_error(error, DBUS_ERROR_FAILED, "%s: failed",
+			       __func__);
+		return FALSE;
+	}
+
+	wpa_printf(MSG_DEBUG, "dbus: Get interface type: %s", char_iftype);
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&iftype, error);
+}
 
 /**
  * wpas_dbus_getter_current_bss - Get current bss object path
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index f6a83cd..cd350f7 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -205,6 +205,9 @@ dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
 dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
 				    void *user_data);
 
+dbus_bool_t wpas_dbus_getter_iftype(DBusMessageIter *iter, DBusError *error,
+				    void *user_data);
+
 dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
 					   DBusError *error,
 					   void *user_data);
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 4a6d38c..f0aba68 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -136,6 +136,16 @@ static inline int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid)
 	return -1;
 }
 
+static inline int
+wpa_drv_get_iftype(struct wpa_supplicant *wpa_s, char *iftype_str)
+
+{
+	if (wpa_s->driver->get_iftype) {
+		return wpa_s->driver->get_iftype(wpa_s->drv_priv, iftype_str);
+	}
+	return -1;
+}
+
 static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s,
 				  enum wpa_alg alg, const u8 *addr,
 				  int key_idx, int set_tx,
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 06b09ef..d01cbf5 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -183,9 +183,16 @@ void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 {
 	int bssid_changed;
+	char old_iftype[IFTYPE_SZ], new_iftype[IFTYPE_SZ];
+
+	memset(&old_iftype, 0, IFTYPE_SZ);
+	memset(&new_iftype, 0, IFTYPE_SZ);
 
 	wnm_bss_keep_alive_deinit(wpa_s);
 
+	if (wpa_drv_get_iftype(wpa_s, old_iftype))
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get old iftype!");
+
 #ifdef CONFIG_IBSS_RSN
 	ibss_rsn_deinit(wpa_s->ibss_rsn);
 	wpa_s->ibss_rsn = NULL;
@@ -230,6 +237,13 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 	wpa_s->key_mgmt = 0;
 
 	wpas_rrm_reset(wpa_s);
+
+	if (wpa_drv_get_iftype(wpa_s, new_iftype)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
+		return;
+	}
+	if (strcmp(new_iftype, old_iftype))
+		wpas_notify_interface_type_changed(wpa_s->global);
 }
 
 
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index c8cfa47..295af1d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -470,6 +470,10 @@ void wpas_notify_debug_level_changed(struct wpa_global *global)
 	wpas_dbus_signal_debug_level_changed(global);
 }
 
+void wpas_notify_interface_type_changed(struct wpa_global *global)
+{
+	wpas_dbus_signal_interface_type_changed(global);
+}
 
 void wpas_notify_debug_timestamp_changed(struct wpa_global *global)
 {
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 7feb530..41555c1 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -78,6 +78,7 @@ void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name);
 void wpas_notify_debug_level_changed(struct wpa_global *global);
 void wpas_notify_debug_timestamp_changed(struct wpa_global *global);
 void wpas_notify_debug_show_keys_changed(struct wpa_global *global);
+void wpas_notify_interface_type_changed(struct wpa_global *global);
 void wpas_notify_suspend(struct wpa_global *global);
 void wpas_notify_resume(struct wpa_global *global);
 
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index aac3a10..7eb0147 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -481,6 +481,10 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
 	struct wpa_ssid *ssid;
 	char *gtype;
 	const char *reason;
+	char old_iftype[IFTYPE_SZ], new_iftype[IFTYPE_SZ];
+
+	memset(&old_iftype, 0, IFTYPE_SZ);
+	memset(&new_iftype, 0, IFTYPE_SZ);
 
 	ssid = wpa_s->current_ssid;
 	if (ssid == NULL) {
@@ -528,6 +532,9 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
 		}
 	}
 
+	if (wpa_drv_get_iftype(wpa_s, old_iftype)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get old iftype!");
+	}
 	if (wpa_s->cross_connect_in_use) {
 		wpa_s->cross_connect_in_use = 0;
 		wpa_msg_global(wpa_s->parent, MSG_INFO,
@@ -649,6 +656,12 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
 	else
 		wpa_drv_deinit_p2p_cli(wpa_s);
 
+	if (wpa_drv_get_iftype(wpa_s, new_iftype)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
+		return 0;
+	}
+	if (strcmp(new_iftype, old_iftype))
+		wpas_notify_interface_type_changed(wpa_s->global);
 	return 0;
 }
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 9d4a14e..25f8545 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1611,6 +1611,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 	int wep_keys_set = 0;
 	int assoc_failed = 0;
 	struct wpa_ssid *old_ssid;
+	char old_iftype[IFTYPE_SZ], new_iftype[IFTYPE_SZ];
 #ifdef CONFIG_HT_OVERRIDES
 	struct ieee80211_ht_capabilities htcaps;
 	struct ieee80211_ht_capabilities htcaps_mask;
@@ -1620,6 +1621,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
        struct ieee80211_vht_capabilities vhtcaps_mask;
 #endif /* CONFIG_VHT_OVERRIDES */
 
+	memset(&old_iftype, 0, IFTYPE_SZ);
+	memset(&new_iftype, 0, IFTYPE_SZ);
+
+	if (wpa_drv_get_iftype(wpa_s, old_iftype))
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get old iftype!");
+
 	if (deinit) {
 		if (work->started) {
 			wpa_s->connect_work = NULL;
@@ -2111,6 +2118,12 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 	wpa_supplicant_initiate_eapol(wpa_s);
 	if (old_ssid != wpa_s->current_ssid)
 		wpas_notify_network_changed(wpa_s);
+	if (wpa_drv_get_iftype(wpa_s, new_iftype)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
+		return;
+	}
+	if (strcmp(new_iftype, old_iftype))
+		wpas_notify_interface_type_changed(wpa_s->global);
 }
 
 
@@ -2145,12 +2158,19 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
 	u8 *addr = NULL;
 	union wpa_event_data event;
 	int zero_addr = 0;
+	char old_iftype[IFTYPE_SZ], new_iftype[IFTYPE_SZ];
+
+	memset(&old_iftype, 0, IFTYPE_SZ);
+	memset(&new_iftype, 0, IFTYPE_SZ);
 
 	wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
 		" pending_bssid=" MACSTR " reason=%d state=%s",
 		MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
 		reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
 
+	if (wpa_drv_get_iftype(wpa_s, old_iftype))
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get old iftype!");
+
 	if (!is_zero_ether_addr(wpa_s->bssid))
 		addr = wpa_s->bssid;
 	else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
@@ -2191,6 +2211,14 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
 	}
 
 	wpa_supplicant_clear_connection(wpa_s, addr);
+
+	if (wpa_drv_get_iftype(wpa_s, new_iftype)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
+		return;
+	}
+	if (strcmp(new_iftype, old_iftype))
+		wpas_notify_interface_type_changed(wpa_s->global);
+
 }
 
 static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index a5227dd..f1b4a7d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -942,6 +942,7 @@ int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
 int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s);
 
 const char * wpa_supplicant_state_txt(enum wpa_states state);
+const char * wpa_supplicant_iftype_txt(int iftype);
 int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
-- 
1.8.1.4



More information about the HostAP mailing list