diff mbox

supplicant: add dbus getter method for nl80211 iftype

Message ID CAJwzM1kVVdFROQcaAmbzSnXwDskj-YB8HXfZVAQsYyzdADGceA@mail.gmail.com
State Changes Requested
Headers show

Commit Message

Avinash Patil Nov. 6, 2014, 7:14 a.m. UTC
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.

Reviewed-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: Avinash Patil <avinashapatil@gmail.com>
---
 src/common/defs.h                       | 18 ++++++++++++
 src/drivers/driver.h                    | 12 ++++++++
 src/drivers/driver_nl80211.c            | 11 +++++++
 wpa_supplicant/dbus/dbus_new.c          | 16 ++++++++++
 wpa_supplicant/dbus/dbus_new.h          |  6 ++++
 wpa_supplicant/dbus/dbus_new_handlers.c | 38 ++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  3 ++
 wpa_supplicant/driver_i.h               |  8 +++++
 wpa_supplicant/events.c                 | 11 ++++++-
 wpa_supplicant/notify.c                 |  6 ++++
 wpa_supplicant/notify.h                 |  1 +
 wpa_supplicant/p2p_supplicant.c         |  9 ++++++
 wpa_supplicant/wpa_supplicant.c         | 52 +++++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h       |  1 +
 14 files changed, 191 insertions(+), 1 deletion(-)

 int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
--
1.8.1.4

Comments

Patrik Flykt Nov. 10, 2014, 2:09 p.m. UTC | #1
Hi,

On Thu, 2014-11-06 at 12:44 +0530, Avinash Patil wrote:
> 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.

I'm perhaps now missing something essential with wpa_supplicant, but
isn't this information supposed to already be part of "Capabilities" in
wpas_dbus_interface_properties[] array? I noticed code checking for
WPA_DRIVER_FLAGS_AP and WPA_DRIVER_FLAGS_P2P_CAPABLE in
wpas_dbus_getter_capabilities() in
wpa_supplicant/dbus/dbus_new_handlers.c, with the assumption that they
are returned to the caller in the D-Bus method call return.


Cheers,

	Patrik
Dan Williams Nov. 10, 2014, 5:13 p.m. UTC | #2
On Mon, 2014-11-10 at 16:09 +0200, Patrik Flykt wrote:
> 	Hi,
> 
> On Thu, 2014-11-06 at 12:44 +0530, Avinash Patil wrote:
> > 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.
> 
> I'm perhaps now missing something essential with wpa_supplicant, but
> isn't this information supposed to already be part of "Capabilities" in
> wpas_dbus_interface_properties[] array? I noticed code checking for
> WPA_DRIVER_FLAGS_AP and WPA_DRIVER_FLAGS_P2P_CAPABLE in
> wpas_dbus_getter_capabilities() in
> wpa_supplicant/dbus/dbus_new_handlers.c, with the assumption that they
> are returned to the caller in the D-Bus method call return.

Capabilities is the list of all interface types that *could* be used,
but I think the point of this patch is to indicate what the current
interface type actually is right now.

Dan
Avinash Patil Nov. 11, 2014, 11:04 a.m. UTC | #3
Hi Patrik,

As Dan said, a device can advertise support for muliple interface
types e.g station, AP, P2P client, GO. Capabilities is bitmap for
this.
But at certain time, device would have only one of these modes
configured e.g. station mode or AP mode. Purpose of this patch is to
get current interface type of device.

Hope this helps.

Thanks,
Avinash

On Mon, Nov 10, 2014 at 10:43 PM, Dan Williams <dcbw@redhat.com> wrote:
> On Mon, 2014-11-10 at 16:09 +0200, Patrik Flykt wrote:
>>       Hi,
>>
>> On Thu, 2014-11-06 at 12:44 +0530, Avinash Patil wrote:
>> > 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.
>>
>> I'm perhaps now missing something essential with wpa_supplicant, but
>> isn't this information supposed to already be part of "Capabilities" in
>> wpas_dbus_interface_properties[] array? I noticed code checking for
>> WPA_DRIVER_FLAGS_AP and WPA_DRIVER_FLAGS_P2P_CAPABLE in
>> wpas_dbus_getter_capabilities() in
>> wpa_supplicant/dbus/dbus_new_handlers.c, with the assumption that they
>> are returned to the caller in the D-Bus method call return.
>
> Capabilities is the list of all interface types that *could* be used,
> but I think the point of this patch is to indicate what the current
> interface type actually is right now.
>
> Dan
>
Jouni Malinen Nov. 15, 2014, 9:17 a.m. UTC | #4
On Thu, Nov 06, 2014 at 12:44:14PM +0530, Avinash Patil wrote:
> 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.

This has significant whitespace damage in the inline patch.. Could you
please resend with those fixed? For example:

checking file src/drivers/driver_nl80211.c
patch: **** malformed patch at line 196: *priv, u8 *bssid)

> diff --git a/src/common/defs.h b/src/common/defs.h
> @@ -297,6 +297,24 @@ enum wpa_ctrl_req_type {
>         NUM_WPA_CTRL_REQS
>  };
> 
> +enum wpa_nl80211_iftype {

nl80211 should not really show up in any way in defs.h. In addition, it
is a bit strange to see interface types defined here, i.e., I would have
expected to see this in src/drivers/driver.h.

> +       WPA_IFTYPE_UNSPECIFIED,
..

> +       /* keep last */
> +       WPA_NL80211_IFTYPES,
> +       WPA_IFTYPE_MAX = WPA_NL80211_IFTYPES - 1

What would these be used for? There was nothing using these in the
patch..


> diff --git a/src/drivers/driver.h b/src/drivers/driver.h
> @@ -1427,6 +1427,18 @@ struct wpa_driver_ops {
>         /**
> +        * get_iftype - Get the current NL80211 iftype

driver.h is supposed to define a driver independent interface. This
should not be documented as being specific to nl80211.

> +       int (*get_iftype)(void *priv, u8 *iftype);

u8 * ??

Shouldn't this be that enum wpa_nl80211_iftype (or well, renamed to
something not nl80211 specific) and the enum defined in this file?

> +static int wpa_driver_nl80211_get_nl80211_iftype(void *priv, u8 *iftype)
> +{
> +       struct i802_bss *bss = priv;
> +       if (!bss)
> +               return -1;
> +
> +       *iftype = (u8)nl80211_get_ifmode(bss);
> +
> +       return 0;
> +}

This would need to map driver interface (nl80211) specific values to
generic values defined in driver.h. That said, I'm not sure I really
understand why we would expose every nl80211 iftype to external programs
through wpa_supplicant. What is the real need for that information? Is
it just something like "is this interface configured in AP mode"? I'd
assume something much simpler would cover that need..

> +       if(wpa_drv_get_iftype(wpa_s, &iftype)) {

"if (wpa_drv..."

> +       char_iftype =  wpa_supplicant_iftype_txt(iftype);

"char_iftype = wpa_..."

> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index 6761c1a..3a075c8 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -182,9 +182,12 @@ void wpa_supplicant_stop_countermeasures(void
> *eloop_ctx, void *sock_ctx)
>  void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
>  {
>         int bssid_changed;
> -
> +       u8 old_iftype = 0, new_iftype = 0;
>         wnm_bss_keep_alive_deinit(wpa_s);

Should not move that empty line in that way.. And why use u8 for
something that seemed to get an enum defined for it?

> +       if(wpa_drv_get_iftype(wpa_s, &new_iftype)) {
> +               wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
> +       }
> +       if (new_iftype != old_iftype)
> +               wpas_notify_interface_type_changed(wpa_s->global);

Why would interface type be reported to change if wpa_drv_get_iftype()
failed?
Avinash Patil Dec. 4, 2014, 11:45 a.m. UTC | #5
Hi Jouni,

Thanks for review.
I will submit a v2 where we wont be exposing interface type outside drivers
i.e. driver_nl80211.
Also I will take care of formatting comments.

Thanks,
Avinash

On Sat, Nov 15, 2014 at 2:47 PM, Jouni Malinen <j@w1.fi> wrote:

> On Thu, Nov 06, 2014 at 12:44:14PM +0530, Avinash Patil wrote:
> > 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.
>
> This has significant whitespace damage in the inline patch.. Could you
> please resend with those fixed? For example:
>
> checking file src/drivers/driver_nl80211.c
> patch: **** malformed patch at line 196: *priv, u8 *bssid)
>
> > diff --git a/src/common/defs.h b/src/common/defs.h
> > @@ -297,6 +297,24 @@ enum wpa_ctrl_req_type {
> >         NUM_WPA_CTRL_REQS
> >  };
> >
> > +enum wpa_nl80211_iftype {
>
> nl80211 should not really show up in any way in defs.h. In addition, it
> is a bit strange to see interface types defined here, i.e., I would have
> expected to see this in src/drivers/driver.h.
>
> > +       WPA_IFTYPE_UNSPECIFIED,
> ..
>
> > +       /* keep last */
> > +       WPA_NL80211_IFTYPES,
> > +       WPA_IFTYPE_MAX = WPA_NL80211_IFTYPES - 1
>
> What would these be used for? There was nothing using these in the
> patch..
>
>
> > diff --git a/src/drivers/driver.h b/src/drivers/driver.h
> > @@ -1427,6 +1427,18 @@ struct wpa_driver_ops {
> >         /**
> > +        * get_iftype - Get the current NL80211 iftype
>
> driver.h is supposed to define a driver independent interface. This
> should not be documented as being specific to nl80211.
>
> > +       int (*get_iftype)(void *priv, u8 *iftype);
>
> u8 * ??
>
> Shouldn't this be that enum wpa_nl80211_iftype (or well, renamed to
> something not nl80211 specific) and the enum defined in this file?
>
> > +static int wpa_driver_nl80211_get_nl80211_iftype(void *priv, u8 *iftype)
> > +{
> > +       struct i802_bss *bss = priv;
> > +       if (!bss)
> > +               return -1;
> > +
> > +       *iftype = (u8)nl80211_get_ifmode(bss);
> > +
> > +       return 0;
> > +}
>
> This would need to map driver interface (nl80211) specific values to
> generic values defined in driver.h. That said, I'm not sure I really
> understand why we would expose every nl80211 iftype to external programs
> through wpa_supplicant. What is the real need for that information? Is
> it just something like "is this interface configured in AP mode"? I'd
> assume something much simpler would cover that need..
>
> > +       if(wpa_drv_get_iftype(wpa_s, &iftype)) {
>
> "if (wpa_drv..."
>
> > +       char_iftype =  wpa_supplicant_iftype_txt(iftype);
>
> "char_iftype = wpa_..."
>
> > diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> > index 6761c1a..3a075c8 100644
> > --- a/wpa_supplicant/events.c
> > +++ b/wpa_supplicant/events.c
> > @@ -182,9 +182,12 @@ void wpa_supplicant_stop_countermeasures(void
> > *eloop_ctx, void *sock_ctx)
> >  void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
> >  {
> >         int bssid_changed;
> > -
> > +       u8 old_iftype = 0, new_iftype = 0;
> >         wnm_bss_keep_alive_deinit(wpa_s);
>
> Should not move that empty line in that way.. And why use u8 for
> something that seemed to get an enum defined for it?
>
> > +       if(wpa_drv_get_iftype(wpa_s, &new_iftype)) {
> > +               wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
> > +       }
> > +       if (new_iftype != old_iftype)
> > +               wpas_notify_interface_type_changed(wpa_s->global);
>
> Why would interface type be reported to change if wpa_drv_get_iftype()
> failed?
>
> --
> Jouni Malinen                                            PGP id EFC895FA
>
diff mbox

Patch

diff --git a/src/common/defs.h b/src/common/defs.h
index bf992e0..8f51e3c 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -297,6 +297,24 @@  enum wpa_ctrl_req_type {
        NUM_WPA_CTRL_REQS
 };

+enum wpa_nl80211_iftype {
+       WPA_IFTYPE_UNSPECIFIED,
+       WPA_IFTYPE_ADHOC,
+       WPA_IFTYPE_STATION,
+       WPA_IFTYPE_AP,
+       WPA_IFTYPE_AP_VLAN,
+       WPA_IFTYPE_WDS,
+       WPA_IFTYPE_MONITOR,
+       WPA_IFTYPE_MESH_POINT,
+       WPA_IFTYPE_P2P_CLIENT,
+       WPA_IFTYPE_P2P_GO,
+       WPA_IFTYPE_P2P_DEVICE,
+
+       /* keep last */
+       WPA_NL80211_IFTYPES,
+       WPA_IFTYPE_MAX = WPA_NL80211_IFTYPES - 1
+};
+
 /* Maximum number of EAP methods to store for EAP server user information */
 #define EAP_MAX_METHODS 8

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 8420a56..a2a2331 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1427,6 +1427,18 @@  struct wpa_driver_ops {
        int (*get_ssid)(void *priv, u8 *ssid);

        /**
+        * get_iftype - Get the current NL80211 iftype
+        * @priv: private driver interface data
+        * @iftype: buffer for storing iftype
+        *
+        * Returns: 0 on success, -1 on failure
+        *
+        * Query kernel driver for the current NL80211 mode and copy it to
+        * iftype.
+        */
+       int (*get_iftype)(void *priv, u8 *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 68afcf0..0909ff2 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -737,6 +737,16 @@  static int wpa_driver_nl80211_get_bssid(void
*priv, u8 *bssid)
        return 0;
 }

+static int wpa_driver_nl80211_get_nl80211_iftype(void *priv, u8 *iftype)
+{
+       struct i802_bss *bss = priv;
+       if (!bss)
+               return -1;
+
+       *iftype = (u8)nl80211_get_ifmode(bss);
+
+       return 0;
+}

 static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
 {
@@ -9081,6 +9091,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..966709d 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2037,6 +2037,18 @@  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 +2968,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 aaaf4f0..25a5c30 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3166,6 +3166,44 @@  dbus_bool_t
wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
                                                &driver, error);
 }

+/**
+ * wpas_dbus_getter_current_mode -
+ * Get current NL mode
+ * @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 "Current IF type" property.
+ */
+dbus_bool_t wpas_dbus_getter_iftype(DBusMessageIter *iter, DBusError *error,
+                                   void *user_data)
+{
+       struct wpa_supplicant *wpa_s = user_data;
+       u8 iftype;
+       const char *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, &iftype)) {
+               wpa_printf(MSG_DEBUG, "wpas_dbus_getter_iftype[dbus]: "
+                          "failed");
+               dbus_set_error(error, DBUS_ERROR_FAILED, "%s: failed",
+                              __func__);
+               return FALSE;
+       }
+       char_iftype =  wpa_supplicant_iftype_txt(iftype);
+
+       wpa_printf(MSG_DEBUG, "dbus: Get interface type: %s", char_iftype);
+       return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+                                               &char_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 18a5457..3e87c85 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -136,6 +136,14 @@  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, u8 *iftype)
+{
+       if (wpa_s->driver->get_iftype) {
+               return wpa_s->driver->get_iftype(wpa_s->drv_priv, iftype);
+       }
+       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 6761c1a..3a075c8 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -182,9 +182,12 @@  void wpa_supplicant_stop_countermeasures(void
*eloop_ctx, void *sock_ctx)
 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 {
        int bssid_changed;
-
+       u8 old_iftype = 0, new_iftype = 0;
        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;
@@ -227,6 +230,12 @@  void wpa_supplicant_mark_disassoc(struct
wpa_supplicant *wpa_s)
        wpa_s->current_ssid = NULL;
        eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
        wpa_s->key_mgmt = 0;
+
+       if(wpa_drv_get_iftype(wpa_s, &new_iftype)) {
+               wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
+       }
+       if (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..66cc49c 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -471,6 +471,12 @@  void wpas_notify_debug_level_changed(struct
wpa_global *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)
 {
        wpas_dbus_signal_debug_timestamp_changed(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..bf690b0 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -480,6 +480,7 @@  static int wpas_p2p_group_delete(struct
wpa_supplicant *wpa_s,
 {
        struct wpa_ssid *ssid;
        char *gtype;
+       u8 old_iftype = 0, new_iftype = 0;
        const char *reason;

        ssid = wpa_s->current_ssid;
@@ -528,6 +529,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 +653,11 @@  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!");
+       }
+       if (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 5a4d8dc..f325a28 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -597,6 +597,39 @@  const char * wpa_supplicant_state_txt(enum
wpa_states state)
        }
 }

+/**
+ * wpa_supplicant_iftype_txt - Get the NL80211 iftype as a text string
+ * Returns: The iftype name as a printable text string
+ */
+const char * wpa_supplicant_iftype_txt(u8 iftype)
+{
+       switch (iftype) {
+       case WPA_IFTYPE_UNSPECIFIED:
+               return "UNSPECIFIED";
+       case WPA_IFTYPE_ADHOC:
+               return "ADHOC";
+       case WPA_IFTYPE_STATION:
+               return "STATION";
+       case WPA_IFTYPE_AP:
+               return "AP";
+       case WPA_IFTYPE_AP_VLAN:
+               return "AP_VLAN";
+       case WPA_IFTYPE_WDS:
+               return "WDS";
+       case WPA_IFTYPE_MONITOR:
+               return "MONITOR";
+       case WPA_IFTYPE_MESH_POINT:
+               return "MESH_POINT";
+       case WPA_IFTYPE_P2P_CLIENT:
+               return "P2P_CLIENT";
+       case WPA_IFTYPE_P2P_GO:
+               return "P2P_GO";
+       case WPA_IFTYPE_P2P_DEVICE:
+               return "P2P_DEVICE";
+       default:
+               return "UNKNOWN";
+       }
+}

 #ifdef CONFIG_BGSCAN

@@ -1579,6 +1612,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;
+       u8 old_iftype = 0, new_iftype = 0;
 #ifdef CONFIG_HT_OVERRIDES
        struct ieee80211_ht_capabilities htcaps;
        struct ieee80211_ht_capabilities htcaps_mask;
@@ -1587,6 +1621,9 @@  static void wpas_start_assoc_cb(struct
wpa_radio_work *work, int deinit)
        struct ieee80211_vht_capabilities vhtcaps;
        struct ieee80211_vht_capabilities vhtcaps_mask;
 #endif /* CONFIG_VHT_OVERRIDES */
+       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) {
@@ -2077,6 +2114,11 @@  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!");
+       }
+       if (new_iftype != old_iftype)
+               wpas_notify_interface_type_changed(wpa_s->global);
 }


@@ -2111,12 +2153,17 @@  void wpa_supplicant_deauthenticate(struct
wpa_supplicant *wpa_s,
        u8 *addr = NULL;
        union wpa_event_data event;
        int zero_addr = 0;
+       u8 old_iftype = 0, new_iftype = 0;

        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) &&
@@ -2147,6 +2194,11 @@  void wpa_supplicant_deauthenticate(struct
wpa_supplicant *wpa_s,
                if (zero_addr)
                        addr = NULL;
        }
+       if(wpa_drv_get_iftype(wpa_s, &new_iftype)) {
+               wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get new iftype!");
+       }
+       if (new_iftype != old_iftype)
+               wpas_notify_interface_type_changed(wpa_s->global);

        wpa_supplicant_clear_connection(wpa_s, addr);
 }
diff --git a/wpa_supplicant/wpa_supplicant_i.h
b/wpa_supplicant/wpa_supplicant_i.h
index cadf724..2bccb30 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -903,6 +903,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(u8 iftype);
 int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s);