From j at w1.fi  Wed May  2 08:00:35 2018
From: j at w1.fi (Jouni Malinen)
Date: Wed, 2 May 2018 18:00:35 +0300
Subject: Proposed Patch: Support for wolfSSL
In-Reply-To: <CE258BE9-FCBE-47C0-B7AB-C95AA65320ED@wolfssl.com>
References: <35F71B52-8428-4A0E-B14C-20CFF8CBCA65@wolfssl.com>
 <20180303191907.GA13466@w1.fi>
 <CE258BE9-FCBE-47C0-B7AB-C95AA65320ED@wolfssl.com>
Message-ID: <20180502150035.GA31057@w1.fi>

On Thu, Mar 29, 2018 at 02:55:55PM +1000, Sean Parkinson wrote:
> I?ve looked into the failures and made changes as needed.
> There were changes to wolfSSL as well.
> 
> To reproduce the setup I tested:
>  - download wolfSSL latest from master (https://github.com/wolfssl/wolfssl)
>  - configure wolfSSL with option -enable-wpas
>  - build wolfSSL
>  - in wpa_supplicant change .config
>    - CONFIG_TLS=wolfssl
>    - disable CONFIG_DPP
> 
> The proposed new patch is below.

Thanks. I applied this as number of smaller commits to make it easier to
review and understand. I did some cleanup and couple of fixes while
going through the changes as well.

There are some remaining issues, but it looks like this is a reasonable
step forward, so I included or the changes even though it looks like
there is something wrong with the ECDH wrappers (at least
crypto_ecdh_set_peerkey() fails to work properly).

The crypto_ecdh_set_peerkey() version in the patch you sent was broken,
i.e., it actually ended up causing process termination due to invalid
wpabuf_put() use that hit the buffer bounds checking routine. I fixed
that to use wpabuf_mhead() instead of wpabuf_put() since the
wc_ecc_import_point_der() call was clearly trying to use the already
generated buffer instead of trying to add something more into the
buffer. While this removed the process termination part, something is
still failing.. That wc_ecc_import_point_der() call fails every now and
then and even if it succeeds, the ECDH shared secret from
wc_ecc_shared_secret_ex() does not match the one that the AP derives
(i.e., using crypto_openssl.c on the other end of the connection).

As far as wolfSSL changes for --enable-wpas case are concerned, please
note that I had to revert the GetName() change in wolfcrypt/src/asn.c
(i.e., do not add an extra '=' to make the one-line name output look
like /CN==FI/ instead of /CN=FI/). This was added in wolfssl commit
b325e0ff916aa5989c523e7619f4dbbbeded74a1 ("Fixes for wpa_supplicant")
for some reason, but it results in a failure in one of the hwsim test
cases that verifies the exact contents of the server certificate name.

As far as remaining failures from wpa_supplicant build using current
wolfSSL snapshot against hostapd build using OpenSSL are concerned, I'm
seeing following issues:
- quite a few EAP-FAST test cases are failing
- ap_wpa2_eap_tls_versions is failing since tls_wolfssl.c returns
  "unknown" from tls_get_version() (i.e., wolfSSL_get_version())
- all OWE test cases are failing (that ECDH issue)
- all FILS PFS test cases are failing (ECDH)
- some EAP protocol test case failures

I haven't looked at these in much detail yet, but this is the list of
failing test cases from my tests:

ap_wpa2_eap_fast_binary_pac
ap_wpa2_eap_fast_binary_pac_errors
ap_wpa2_eap_fast_mschapv2_unauth_prov
ap_wpa2_eap_fast_pac_file
ap_wpa2_eap_fast_pac_refresh
ap_wpa2_eap_fast_pac_truncate
ap_wpa2_eap_fast_prov
ap_wpa2_eap_fast_server_oom
ap_wpa2_eap_fast_text_pac_errors
ap_wpa2_eap_ikev2_oom
ap_wpa2_eap_pwd_groups
ap_wpa2_eap_tls_versions
eap_mschapv2_errors
eap_proto_eke_errors
eap_proto_fast_errors
fils_sk_pfs_20
fils_sk_pfs_21
fils_sk_pfs_26
owe
owe_and_psk
owe_group_negotiation
owe_group_negotiation_connect_cmd
owe_groups
owe_limited_group_set
owe_pmksa_caching
owe_pmksa_caching_connect_cmd
owe_transition_mode
owe_transition_mode_connect_cmd
owe_transition_mode_multi_bss
sigma_dut_ap_owe
sigma_dut_ap_owe_ecgroupid
sigma_dut_ap_owe_transition_mode
sigma_dut_ap_owe_transition_mode_2
sigma_dut_owe

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Wed May  2 08:04:17 2018
From: j at w1.fi (Jouni Malinen)
Date: Wed, 2 May 2018 18:04:17 +0300
Subject: [PATCH] crypto/wolfssl: fix build
In-Reply-To: <20180428190626.GA29778@makrotopia.org>
References: <20180428190626.GA29778@makrotopia.org>
Message-ID: <20180502150417.GB31057@w1.fi>

On Sat, Apr 28, 2018 at 09:06:32PM +0200, Daniel Golle wrote:
> Replace non-existing config-symbol and fix variable-name typo which
> caused the build to fail with CONFIG_TLS=wolfssl.

> diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c

> -#ifdef CONFIG_DES
> +#ifndef CONFIG_INTERNAL_DES
>  int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
>  {
>  	Des des;
> @@ -312,7 +312,7 @@ int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
>  
>  	return 0;
>  }
> -#endif /* CONFIG_DES */
> +#endif /* !CONFIG_INTERNAL_DES */

CONFIG_DES does actually exist (wpa_supplicant/Makefile and
hostapd/Makefile define this for the C pre-processor)..
CONFIG_INTERNAL_DES on the other hand is used only within make and is
not exposed to the C pre-processor. As such, I don't see how this
changes would be appropriate. Do you really need this to fix the build?
If so, it would imply that either there are some other issues in
des_encrypt() is needed without CONFIG_DES getting defined or your build
configuration is invalid (e.g., trying to use CONFIG_FIPS=y with
functionality that needs DES).

> diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
> @@ -2037,14 +2037,14 @@ static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)

> -	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticketLen) != 1)
> +	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticket_len) != 1)

> -				      conn->session_ticket, ticketLen,
> +				      conn->session_ticket, ticket_len,

These were already covered by the earlier patches from Sean.

-- 
Jouni Malinen                                            PGP id EFC895FA


From kkrishnamoorthy at quantenna.com  Thu May  3 01:37:08 2018
From: kkrishnamoorthy at quantenna.com (Karthik Krishnamoorthy)
Date: Thu, 3 May 2018 08:37:08 +0000
Subject: Is PMF with development branch working?
Message-ID: <BN6PR05MB3602ADB99AB4934173ABC43FBB870@BN6PR05MB3602.namprd05.prod.outlook.com>

Hi,

I am working on the development branch for hostapd.

I started testing PMF mode , with ieee80211w=1.

>From testing what I see is the client fails to associate.

On sniffer analysis , I found that Message 3 from AP is not proper.

Especially the WPA key data length is 88 bytes.

Whereas when I compare this with hostapd 2.1 version , the WPA key data length is 96 bytes.

There is 8 byte mismatch in the M3 message from AP between hostapd version 2.1 and latest development branch version.

Clients associate with hostapd 2.1 version, so I believe that is a correct length.

Anyone seen this behaviour or is this fixed already? Do I need to sync to latest code?

Thanks and Regards,
Karthik.





This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From j at w1.fi  Thu May  3 02:22:12 2018
From: j at w1.fi (Jouni Malinen)
Date: Thu, 3 May 2018 12:22:12 +0300
Subject: Is PMF with development branch working?
In-Reply-To: <BN6PR05MB3602ADB99AB4934173ABC43FBB870@BN6PR05MB3602.namprd05.prod.outlook.com>
References: <BN6PR05MB3602ADB99AB4934173ABC43FBB870@BN6PR05MB3602.namprd05.prod.outlook.com>
Message-ID: <20180503092212.GA6618@w1.fi>

On Thu, May 03, 2018 at 08:37:08AM +0000, Karthik Krishnamoorthy wrote:
> I am working on the development branch for hostapd.
> 
> I started testing PMF mode , with ieee80211w=1.
> 
> From testing what I see is the client fails to associate.
> 
> On sniffer analysis , I found that Message 3 from AP is not proper.

Can you please share a sniffer capture file showing this, the
hostapd.conf file used in the test, and debug log from hostapd (ideally,
using some dummy passphrase/password and -ddK on the command like to
expose all key material)?

Which client did you use in the test? And what do you mean with "fails
to associate"? 4-way handshake is started only after the association has
been completed, so if you get to Message 3 of the 4-way handshake, the
client has already associated..

> Especially the WPA key data length is 88 bytes.
> 
> Whereas when I compare this with hostapd 2.1 version , the WPA key data length is 96 bytes.
> 
> There is 8 byte mismatch in the M3 message from AP between hostapd version 2.1 and latest development branch version.

The length of the Key Data field depends on the contents of the RSN
element and group cipher, so both of those lengths can be valid.

> Clients associate with hostapd 2.1 version, so I believe that is a correct length.

There is no specific "correct length". For example, a commonly used RSNE
of 22 octets (ending with the RSN Capabilities subfield), CCMP as the
group ciphers, and BIP as the group management cipher ends up having
22+24+30=76 octets of IEs/KDEs in the plaintext version. That gets
padded with 4 octets to 80 octets to make this a multiple of 8. And AES
Key Wrap adds 8 octets to the length, so the total encrypted length of
the Key Data field becomes 88 octets.

> Anyone seen this behaviour or is this fixed already? Do I need to sync to latest code?

I'm not aware of any issues in the PMF implementation between version
2.1 and the current snapshot.

-- 
Jouni Malinen                                            PGP id EFC895FA


From nbd at nbd.name  Thu May  3 03:36:15 2018
From: nbd at nbd.name (Felix Fietkau)
Date: Thu,  3 May 2018 12:36:15 +0200
Subject: [PATCH] mesh: fix crash with CONFIG_TAXONOMY enabled
Message-ID: <20180503103615.43710-1-nbd@nbd.name>

wpa_s->ifmsh needs to be allocated using hostapd_alloc_iface() instead
of a direct call to os_zalloc, otherwise the linked list for station
taxonomy items remains uninitialized, leading to a crash on the first
attempt to traverse that list

Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 wpa_supplicant/mesh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 19b66b4b0..c4f167e1c 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -169,7 +169,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 		return 0;
 	}
 
-	wpa_s->ifmsh = ifmsh = os_zalloc(sizeof(*wpa_s->ifmsh));
+	wpa_s->ifmsh = ifmsh = hostapd_alloc_iface();
 	if (!ifmsh)
 		return -ENOMEM;
 
-- 
2.17.0



From bela at becker.rocks  Thu May  3 09:08:16 2018
From: bela at becker.rocks (Becker =?ISO-8859-1?Q?B=E9la?=)
Date: Thu, 03 May 2018 18:08:16 +0200
Subject: [BUG] CAC countdown timer underflow
Message-ID: <4893589.HXiUOUuvTM@maxion>

Hello,

This is the second time this has occured to me in a few days. When selecting a DFS channel, the 60s timer can underflow, it winds up counting from UINT32_MAX.
I'm not able to reproduce this bug consistently, but I guess if I were to try again repeatedly it would randomly happen again.
Is this a known issue? I couldn't find any mention of this on the web.

The module I use is a SparkLAN WPEA-128N (AR9380), on an ARM cpu, running Linux 4.9.84.

root at passanger:~ # hostapd_cli status
Selected interface 'wlp4s0'
state=DFS
phy=phy1
freq=5580
num_sta_non_erp=0
num_sta_no_short_slot_time=0
num_sta_no_short_preamble=0
olbc=0
num_sta_ht_no_gf=0
num_sta_no_ht=0
num_sta_ht_20_mhz=0
num_sta_ht40_intolerant=0
olbc_ht=0
ht_op_mode=0x0
cac_time_seconds=60
cac_time_left_seconds=4294967006
channel=116
secondary_channel=0
ieee80211n=1
ieee80211ac=0
bss[0]=wlp4s0
bssid[0]=00:xx:xx:xx:xx:xx
ssid[0]=test_ap
num_sta[0]=0

root at passanger:~ # hostapd -v
hostapd v2.6
User space daemon for IEEE 802.11 AP management,
IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
Copyright (c) 2002-2016, Jouni Malinen <j at w1.fi> and contributors

root at passanger:~ # uname -a
Linux passanger 4.9.84-2.8.2+gb2a7f2f #13 SMP Thu Apr 26 18:15:49 UTC 2018 armv7l armv7l armv7l GNU/Linux


From bela at becker.rocks  Thu May  3 17:26:25 2018
From: bela at becker.rocks (Becker =?ISO-8859-1?Q?B=E9la?=)
Date: Fri, 04 May 2018 02:26:25 +0200
Subject: [BUG] CAC countdown timer underflow
In-Reply-To: <4893589.HXiUOUuvTM@maxion>
References: <4893589.HXiUOUuvTM@maxion>
Message-ID: <1746948.7mAkBFlpQd@bela>

On 2018. m?jus 3., cs?t?rt?k 18:08:16 CEST Becker B?la wrote:
> Hello,
> 
> This is the second time this has occured to me in a few days. When selecting a DFS channel, the 60s timer can underflow, it winds up counting from UINT32_MAX.
> I'm not able to reproduce this bug consistently, but I guess if I were to try again repeatedly it would randomly happen again.
> Is this a known issue? I couldn't find any mention of this on the web.
> 
> The module I use is a SparkLAN WPEA-128N (AR9380), on an ARM cpu, running Linux 4.9.84.

After digging around and learning more about the WiFi stack, I realize that hostapd does not change that timer, so this bug must somewhere in the ath9k or the cfg80211 drivers.




From kkrishnamoorthy at quantenna.com  Thu May  3 22:47:36 2018
From: kkrishnamoorthy at quantenna.com (Karthik Krishnamoorthy)
Date: Fri, 4 May 2018 05:47:36 +0000
Subject: Is PMF with development branch working?
In-Reply-To: <20180503092212.GA6618@w1.fi>
References: <BN6PR05MB3602ADB99AB4934173ABC43FBB870@BN6PR05MB3602.namprd05.prod.outlook.com>
 <20180503092212.GA6618@w1.fi>
Message-ID: <BN6PR05MB3602489B664E89CB82791BBBBB860@BN6PR05MB3602.namprd05.prod.outlook.com>

Hi Jouni,

I believe to have found the issue:

The issue seems to be in src/ap/wpa_auth_ie.c:

int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
                     const u8 *pmkid)
{

....
....

#ifdef CONFIG_IEEE80211W
if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
    conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {
if (2 + 4 > buf + len - pos)
return -1;
if (pmkid == NULL) {
/* PMKID Count */
WPA_PUT_LE16(pos, 0);
pos += 2;
}

/* Management Group Cipher Suite */
switch (conf->group_mgmt_cipher) {
case WPA_CIPHER_AES_128_CMAC:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
break;
case WPA_CIPHER_BIP_GMAC_128:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
break;
case WPA_CIPHER_BIP_GMAC_256:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
break;
case WPA_CIPHER_BIP_CMAC_256:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256);
break;
default:
wpa_printf(MSG_DEBUG,
   "Invalid group management cipher (0x%x)",
   conf->group_mgmt_cipher);
return -1;
}
pos += RSN_SELECTOR_LEN;
}
#endif /* CONFIG_IEEE80211W */

.....
.....

}

Here the condition check :
if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
    conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {

will be missed since the default group_mgmt_cipher will be WPA_CIPHER_AES_128_CMAC.

Whereas the condition check in hostapd-2.1 is :

if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)

So here the value is set correctly.

If I remove this check (conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) it works properly.

Regards,
Karthik.

-----Original Message-----
From: Jouni Malinen [mailto:j at w1.fi]
Sent: Thursday, 3 May 2018 7:22 PM
To: Karthik Krishnamoorthy <kkrishnamoorthy at quantenna.com>
Cc: hostap at lists.infradead.org
Subject: Re: Is PMF with development branch working?


External Email


On Thu, May 03, 2018 at 08:37:08AM +0000, Karthik Krishnamoorthy wrote:
> I am working on the development branch for hostapd.
>
> I started testing PMF mode , with ieee80211w=1.
>
> From testing what I see is the client fails to associate.
>
> On sniffer analysis , I found that Message 3 from AP is not proper.

Can you please share a sniffer capture file showing this, the hostapd.conf file used in the test, and debug log from hostapd (ideally, using some dummy passphrase/password and -ddK on the command like to expose all key material)?

Which client did you use in the test? And what do you mean with "fails to associate"? 4-way handshake is started only after the association has been completed, so if you get to Message 3 of the 4-way handshake, the client has already associated..

> Especially the WPA key data length is 88 bytes.
>
> Whereas when I compare this with hostapd 2.1 version , the WPA key data length is 96 bytes.
>
> There is 8 byte mismatch in the M3 message from AP between hostapd version 2.1 and latest development branch version.

The length of the Key Data field depends on the contents of the RSN element and group cipher, so both of those lengths can be valid.

> Clients associate with hostapd 2.1 version, so I believe that is a correct length.

There is no specific "correct length". For example, a commonly used RSNE of 22 octets (ending with the RSN Capabilities subfield), CCMP as the group ciphers, and BIP as the group management cipher ends up having
22+24+30=76 octets of IEs/KDEs in the plaintext version. That gets
padded with 4 octets to 80 octets to make this a multiple of 8. And AES Key Wrap adds 8 octets to the length, so the total encrypted length of the Key Data field becomes 88 octets.

> Anyone seen this behaviour or is this fixed already? Do I need to sync to latest code?

I'm not aware of any issues in the PMF implementation between version
2.1 and the current snapshot.

--
Jouni Malinen                                            PGP id EFC895FA


This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From matthewmwang at chromium.org  Thu May  3 16:32:28 2018
From: matthewmwang at chromium.org (Matthew Wang)
Date: Thu,  3 May 2018 16:32:28 -0700
Subject: [PATCH] dbus: export roam time, roam complete,
 and session length to dbus
Message-ID: <20180503233228.46852-1-matthewmwang@chromium.org>

Added new Interface properties "RoamTime", "RoamComplete", and "SessionLength".

"RoamTime" carries the roam time of the most recent roam in milliseconds.
"RoamComplete" carries True or False corresponding to the success status of the
most recent roam.
"SessionLength" carries the number of milliseconds corresponding to how long
the connection to the last AP was before a roam or disconnect happened.

These properties will all be logged in UMA to compare FT vs non-FT network
behaviors.

Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
---
 doc/dbus.doxygen                        | 15 ++++++
 wpa_supplicant/dbus/dbus_new.c          | 27 ++++++++++
 wpa_supplicant/dbus/dbus_new.h          |  3 ++
 wpa_supplicant/dbus/dbus_new_handlers.c | 65 +++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  3 ++
 wpa_supplicant/notify.c                 | 27 ++++++++++
 wpa_supplicant/notify.h                 |  3 ++
 wpa_supplicant/wpa_supplicant.c         | 34 +++++++++++++
 wpa_supplicant/wpa_supplicant_i.h       |  4 ++
 9 files changed, 181 insertions(+)

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index 2ca40ae9b..d3003b31d 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -769,6 +769,21 @@ fi.w1.wpa_supplicant1.CreateInterface.
 	<p>The most recent IEEE 802.11 status code for association rejection.</p>
       </li>
 
+      <li>
+	<h3>RoamTime - i - (read)</h3>
+	<p>The most recent roam time in milliseconds.</p>
+      </li>
+
+      <li>
+	<h3>RoamComplete - b - (read)</h3>
+	<p>The most recent roam success or failure.</p>
+      </li>
+
+      <li>
+	<h3>SessionLength - i - (read)</h3>
+	<p>The most recent BSS session length in milliseconds.</p>
+      </li>
+
       <li>
 	<h3>EapolVersion - s - (read/write)</h3>
 	<p>IEEE 802.1X/EAPOL version number</p>
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index e0f16bbda..168e9baf6 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2162,6 +2162,15 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
 		prop = "AssocStatusCode";
 		flush = TRUE;
 		break;
+	case WPAS_DBUS_PROP_ROAM_TIME:
+		prop = "RoamTime";
+		break;
+	case WPAS_DBUS_PROP_ROAM_COMPLETE:
+		prop = "RoamComplete";
+		break;
+	case WPAS_DBUS_PROP_SESSION_LENGTH:
+		prop = "SessionLength";
+		break;
 	default:
 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
 			   __func__, property);
@@ -2731,6 +2740,24 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
 	  NULL,
 	  NULL
 	},
+	{
+	  "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
+	  wpas_dbus_getter_roam_time,
+	  NULL,
+	  NULL
+	},
+	{
+	  "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
+	  wpas_dbus_getter_roam_complete,
+	  NULL,
+	  NULL
+	},
+	{
+	  "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
+	  wpas_dbus_getter_session_length,
+	  NULL,
+	  NULL
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index e68acb7a1..08f4858b1 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -31,6 +31,9 @@ enum wpas_dbus_prop {
 	WPAS_DBUS_PROP_BSSS,
 	WPAS_DBUS_PROP_DISCONNECT_REASON,
 	WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
+	WPAS_DBUS_PROP_ROAM_TIME,
+	WPAS_DBUS_PROP_ROAM_COMPLETE,
+	WPAS_DBUS_PROP_SESSION_LENGTH,
 };
 
 enum wpas_dbus_bss_prop {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index a3c98fadd..4e3412cdc 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3158,6 +3158,71 @@ dbus_bool_t wpas_dbus_getter_assoc_status_code(
 }
 
 
+/**
+ * wpas_dbus_getter_roam_time - Get most recent roam time
+ * @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 "RoamTime" property.
+ */
+dbus_bool_t wpas_dbus_getter_roam_time(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_int32_t roam_time = wpa_s->roam_time.sec * 1000 +
+				 wpa_s->roam_time.usec / 1000;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
+						&roam_time, error);
+}
+
+/**
+ * wpas_dbus_getter_roam_complete - Get most recent roam success or failure
+ * @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 "RoamComplete" property.
+ */
+dbus_bool_t wpas_dbus_getter_roam_complete(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_bool_t roam_complete = os_reltime_initialized(&wpa_s->roam_time) ?
+				    TRUE : FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&roam_complete, error);
+}
+
+
+/**
+ * wpas_dbus_getter_session_length - Get most recent BSS session length
+ * @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 "SessionLength" property.
+ */
+dbus_bool_t wpas_dbus_getter_session_length(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_int32_t session_length = wpa_s->session_length.sec * 1000 +
+				      wpa_s->session_length.usec / 1000;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
+						&session_length, error);
+}
+
+
 /**
  * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
  * @iter: Pointer to incoming dbus message iter
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 26652ad3d..7a03b7f9f 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -148,6 +148,9 @@ DECLARE_ACCESSOR(wpas_dbus_setter_fast_reauth);
 DECLARE_ACCESSOR(wpas_dbus_getter_disconnect_reason);
 DECLARE_ACCESSOR(wpas_dbus_getter_disassociate_reason);
 DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
+DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
+DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
+DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 83df04f39..a2b04716d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -149,6 +149,33 @@ void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s)
 }
 
 
+void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_TIME);
+}
+
+
+void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_COMPLETE);
+}
+
+
+void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SESSION_LENGTH);
+}
+
+
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->p2p_mgmt)
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 3ca933c76..bde20e83d 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -24,6 +24,9 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
 			       enum wpa_states old_state);
 void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
 void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s);
+void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
+void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
+void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index dcd787bec..df27c55ad 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -839,6 +839,40 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 		wpa_supplicant_state_txt(wpa_s->wpa_state),
 		wpa_supplicant_state_txt(state));
 
+	if (state == WPA_AUTHENTICATING && wpa_s->wpa_state == WPA_COMPLETED) {
+		if (wpa_s->sme.prev_bssid_set &&
+		    os_memcmp(wpa_s->sme.prev_bssid, wpa_s->pending_bssid, ETH_ALEN) != 0) {
+			os_get_reltime(&wpa_s->roam_start);
+		}
+	} else if (state == WPA_COMPLETED &&
+		   os_reltime_initialized(&wpa_s->roam_start)) {
+		os_reltime_age(&wpa_s->roam_start, &wpa_s->roam_time);
+		wpa_s->roam_start.sec = 0;
+		wpa_s->roam_start.usec = 0;
+		wpas_notify_auth_changed(wpa_s);
+		wpas_notify_roam_time(wpa_s);
+		wpas_notify_roam_complete(wpa_s);
+	} else if (state == WPA_DISCONNECTED &&
+		   os_reltime_initialized(&wpa_s->roam_start)) {
+		wpa_s->roam_start.sec = 0;
+		wpa_s->roam_start.usec = 0;
+		wpa_s->roam_time.sec = 0;
+		wpa_s->roam_time.usec = 0;
+		wpas_notify_roam_complete(wpa_s);
+	}
+
+	if (state == WPA_COMPLETED && wpa_s->wpa_state != WPA_COMPLETED) {
+		wpas_notify_auth_changed(wpa_s);
+		os_get_reltime(&wpa_s->session_start);
+	} else if (state != WPA_COMPLETED &&
+		   wpa_s->wpa_state == WPA_COMPLETED &&
+		   os_reltime_initialized(&wpa_s->session_start)) {
+		os_reltime_age(&wpa_s->session_start, &wpa_s->session_length);
+		wpa_s->session_start.sec = 0;
+		wpa_s->session_start.usec = 0;
+		wpas_notify_session_length(wpa_s);
+	}
+
 	if (state == WPA_INTERFACE_DISABLED) {
 		/* Assure normal scan when interface is restored */
 		wpa_s->normal_scans = 0;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 4d18177fb..a4d56b810 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -492,6 +492,10 @@ struct wpa_supplicant {
 	struct wpa_supplicant *next;
 	struct l2_packet_data *l2;
 	struct l2_packet_data *l2_br;
+	struct os_reltime roam_start;
+	struct os_reltime roam_time;
+	struct os_reltime session_start;
+	struct os_reltime session_length;
 	unsigned char own_addr[ETH_ALEN];
 	unsigned char perm_addr[ETH_ALEN];
 	char ifname[100];
-- 
2.17.0.441.gb46fe60e1d-goog



From matthewmwang at chromium.org  Thu May  3 18:00:52 2018
From: matthewmwang at chromium.org (Matthew Wang)
Date: Thu,  3 May 2018 18:00:52 -0700
Subject: [PATCH] dbus: export BSS Transition Management status to dbus
Message-ID: <20180504010052.66020-1-matthewmwang@chromium.org>

Added new Interface properties "BSSTMStatus", which carries the status of
the most recent BSS Transition Management request. This property will be
logged in UMA to measure 802.11v success.

Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
---
 doc/dbus.doxygen                        |  5 +++++
 wpa_supplicant/dbus/dbus_new.c          |  9 +++++++++
 wpa_supplicant/dbus/dbus_new.h          |  1 +
 wpa_supplicant/dbus/dbus_new_handlers.c | 22 ++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  1 +
 wpa_supplicant/notify.c                 |  9 +++++++++
 wpa_supplicant/notify.h                 |  1 +
 wpa_supplicant/wnm_sta.c                |  4 ++++
 wpa_supplicant/wpa_supplicant_i.h       |  1 +
 9 files changed, 53 insertions(+)

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index d3003b31d..cf5129474 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -784,6 +784,11 @@ fi.w1.wpa_supplicant1.CreateInterface.
 	<p>The most recent BSS session length in milliseconds.</p>
       </li>
 
+      <li>
+	<h3>BSSTMStatus - i - (read)</h3>
+	<p>The most recent BSS Transition Management status code.</p>
+      </li>
+
       <li>
 	<h3>EapolVersion - s - (read/write)</h3>
 	<p>IEEE 802.1X/EAPOL version number</p>
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 168e9baf6..2f4b2bf46 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2171,6 +2171,9 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
 	case WPAS_DBUS_PROP_SESSION_LENGTH:
 		prop = "SessionLength";
 		break;
+	case WPAS_DBUS_PROP_BSS_TM_STATUS:
+		prop = "BSSTMStatus";
+		break;
 	default:
 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
 			   __func__, property);
@@ -2758,6 +2761,12 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
 	  NULL,
 	  NULL
 	},
+	{
+	  "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
+	  wpas_dbus_getter_bss_tm_status,
+	  NULL,
+	  NULL
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 08f4858b1..bec9a4153 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -34,6 +34,7 @@ enum wpas_dbus_prop {
 	WPAS_DBUS_PROP_ROAM_TIME,
 	WPAS_DBUS_PROP_ROAM_COMPLETE,
 	WPAS_DBUS_PROP_SESSION_LENGTH,
+	WPAS_DBUS_PROP_BSS_TM_STATUS,
 };
 
 enum wpas_dbus_bss_prop {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 4e3412cdc..367d26d14 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3223,6 +3223,28 @@ dbus_bool_t wpas_dbus_getter_session_length(
 }
 
 
+/**
+ * wpas_dbus_getter_bss_tm_status - Get most BSS Transition Management request
+ * status code
+ * @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 "BSSTMStatus" property.
+ */
+dbus_bool_t wpas_dbus_getter_bss_tm_status(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_int32_t bss_tm_status = wpa_s->bss_tm_status;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
+						&bss_tm_status, error);
+}
+
+
 /**
  * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
  * @iter: Pointer to incoming dbus message iter
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 7a03b7f9f..25ab9991c 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -151,6 +151,7 @@ DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
 DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
 DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
 DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
+DECLARE_ACCESSOR(wpas_dbus_getter_bss_tm_status);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index a2b04716d..b171e8e87 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -176,6 +176,15 @@ void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
 }
 
 
+void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS);
+}
+
+
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->p2p_mgmt)
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index bde20e83d..9605785cf 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -27,6 +27,7 @@ void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s);
 void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
 void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
 void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
+void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index 7c410e730..1dbc90352 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -20,6 +20,7 @@
 #include "ctrl_iface.h"
 #include "bss.h"
 #include "wnm_sta.h"
+#include "notify.h"
 #include "hs20_supplicant.h"
 
 #define MAX_TFS_IE_LEN  1024
@@ -938,6 +939,9 @@ static void wnm_send_bss_transition_mgmt_resp(
 		return;
 	}
 
+        wpa_s->bss_tm_status = status;
+        wpas_notify_bss_tm_status(wpa_s);
+
 	wpabuf_put_u8(buf, WLAN_ACTION_WNM);
 	wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_RESP);
 	wpabuf_put_u8(buf, dialog_token);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index a4d56b810..70da2a4b1 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1059,6 +1059,7 @@ struct wpa_supplicant {
 	struct neighbor_report *wnm_neighbor_report_elements;
 	struct os_reltime wnm_cand_valid_until;
 	u8 wnm_cand_from_bss[ETH_ALEN];
+        enum bss_trans_mgmt_status_code bss_tm_status;
 #ifdef CONFIG_MBO
 	unsigned int wnm_mbo_trans_reason_present:1;
 	u8 wnm_mbo_transition_reason;
-- 
2.17.0.441.gb46fe60e1d-goog



From dcbw at redhat.com  Fri May  4 07:43:49 2018
From: dcbw at redhat.com (Dan Williams)
Date: Fri, 04 May 2018 09:43:49 -0500
Subject: [PATCH] dbus: export roam time, roam complete, and session
 length to dbus
In-Reply-To: <20180503233228.46852-1-matthewmwang@chromium.org>
References: <20180503233228.46852-1-matthewmwang@chromium.org>
Message-ID: <7f094e40cf8395816b36c7731220e2243f5d2d0b.camel@redhat.com>

On Thu, 2018-05-03 at 16:32 -0700, Matthew Wang wrote:
> Added new Interface properties "RoamTime", "RoamComplete", and
> "SessionLength".
> 
> "RoamTime" carries the roam time of the most recent roam in
> milliseconds.
> "RoamComplete" carries True or False corresponding to the success
> status of the
> most recent roam.
> "SessionLength" carries the number of milliseconds corresponding to
> how long
> the connection to the last AP was before a roam or disconnect
> happened.
> 
> These properties will all be logged in UMA to compare FT vs non-FT
> network
> behaviors.
> 
> Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
> ---
>  doc/dbus.doxygen                        | 15 ++++++
>  wpa_supplicant/dbus/dbus_new.c          | 27 ++++++++++
>  wpa_supplicant/dbus/dbus_new.h          |  3 ++
>  wpa_supplicant/dbus/dbus_new_handlers.c | 65
> +++++++++++++++++++++++++
>  wpa_supplicant/dbus/dbus_new_handlers.h |  3 ++
>  wpa_supplicant/notify.c                 | 27 ++++++++++
>  wpa_supplicant/notify.h                 |  3 ++
>  wpa_supplicant/wpa_supplicant.c         | 34 +++++++++++++
>  wpa_supplicant/wpa_supplicant_i.h       |  4 ++
>  9 files changed, 181 insertions(+)
> 
> diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
> index 2ca40ae9b..d3003b31d 100644
> --- a/doc/dbus.doxygen
> +++ b/doc/dbus.doxygen
> @@ -769,6 +769,21 @@ fi.w1.wpa_supplicant1.CreateInterface.
>  	<p>The most recent IEEE 802.11 status code for association
> rejection.</p>
>        </li>
>  
> +      <li>
> +	<h3>RoamTime - i - (read)</h3>
> +	<p>The most recent roam time in milliseconds.</p>
> +      </li>

Any reason to have RoamTime and SessionLength be int, rather than uint?
 Are they ever going to be less than zero?

Dan

> +      <li>
> +	<h3>RoamComplete - b - (read)</h3>
> +	<p>The most recent roam success or failure.</p>
> +      </li>
> +
> +      <li>
> +	<h3>SessionLength - i - (read)</h3>
> +	<p>The most recent BSS session length in milliseconds.</p>
> +      </li>
> +
>        <li>
>  	<h3>EapolVersion - s - (read/write)</h3>
>  	<p>IEEE 802.1X/EAPOL version number</p>
> diff --git a/wpa_supplicant/dbus/dbus_new.c
> b/wpa_supplicant/dbus/dbus_new.c
> index e0f16bbda..168e9baf6 100644
> --- a/wpa_supplicant/dbus/dbus_new.c
> +++ b/wpa_supplicant/dbus/dbus_new.c
> @@ -2162,6 +2162,15 @@ void wpas_dbus_signal_prop_changed(struct
> wpa_supplicant *wpa_s,
>  		prop = "AssocStatusCode";
>  		flush = TRUE;
>  		break;
> +	case WPAS_DBUS_PROP_ROAM_TIME:
> +		prop = "RoamTime";
> +		break;
> +	case WPAS_DBUS_PROP_ROAM_COMPLETE:
> +		prop = "RoamComplete";
> +		break;
> +	case WPAS_DBUS_PROP_SESSION_LENGTH:
> +		prop = "SessionLength";
> +		break;
>  	default:
>  		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property
> value %d",
>  			   __func__, property);
> @@ -2731,6 +2740,24 @@ static const struct wpa_dbus_property_desc
> wpas_dbus_bss_properties[] = {
>  	  NULL,
>  	  NULL
>  	},
> +	{
> +	  "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
> +	  wpas_dbus_getter_roam_time,
> +	  NULL,
> +	  NULL
> +	},
> +	{
> +	  "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
> +	  wpas_dbus_getter_roam_complete,
> +	  NULL,
> +	  NULL
> +	},
> +	{
> +	  "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
> +	  wpas_dbus_getter_session_length,
> +	  NULL,
> +	  NULL
> +	},
>  	{ NULL, NULL, NULL, NULL, NULL, NULL }
>  };
>  
> diff --git a/wpa_supplicant/dbus/dbus_new.h
> b/wpa_supplicant/dbus/dbus_new.h
> index e68acb7a1..08f4858b1 100644
> --- a/wpa_supplicant/dbus/dbus_new.h
> +++ b/wpa_supplicant/dbus/dbus_new.h
> @@ -31,6 +31,9 @@ enum wpas_dbus_prop {
>  	WPAS_DBUS_PROP_BSSS,
>  	WPAS_DBUS_PROP_DISCONNECT_REASON,
>  	WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
> +	WPAS_DBUS_PROP_ROAM_TIME,
> +	WPAS_DBUS_PROP_ROAM_COMPLETE,
> +	WPAS_DBUS_PROP_SESSION_LENGTH,
>  };
>  
>  enum wpas_dbus_bss_prop {
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c
> b/wpa_supplicant/dbus/dbus_new_handlers.c
> index a3c98fadd..4e3412cdc 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.c
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.c
> @@ -3158,6 +3158,71 @@ dbus_bool_t
> wpas_dbus_getter_assoc_status_code(
>  }
>  
>  
> +/**
> + * wpas_dbus_getter_roam_time - Get most recent roam time
> + * @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 "RoamTime" property.
> + */
> +dbus_bool_t wpas_dbus_getter_roam_time(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct wpa_supplicant *wpa_s = user_data;
> +	dbus_int32_t roam_time = wpa_s->roam_time.sec * 1000 +
> +				 wpa_s->roam_time.usec / 1000;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_INT32,
> +						&roam_time, error);
> +}
> +
> +/**
> + * wpas_dbus_getter_roam_complete - Get most recent roam success or
> failure
> + * @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 "RoamComplete" property.
> + */
> +dbus_bool_t wpas_dbus_getter_roam_complete(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct wpa_supplicant *wpa_s = user_data;
> +	dbus_bool_t roam_complete = os_reltime_initialized(&wpa_s-
> >roam_time) ?
> +				    TRUE : FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_BOOLEAN,
> +						&roam_complete,
> error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_session_length - Get most recent BSS session
> length
> + * @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 "SessionLength" property.
> + */
> +dbus_bool_t wpas_dbus_getter_session_length(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct wpa_supplicant *wpa_s = user_data;
> +	dbus_int32_t session_length = wpa_s->session_length.sec *
> 1000 +
> +				      wpa_s->session_length.usec /
> 1000;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_INT32,
> +						&session_length,
> error);
> +}
> +
> +
>  /**
>   * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
>   * @iter: Pointer to incoming dbus message iter
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h
> b/wpa_supplicant/dbus/dbus_new_handlers.h
> index 26652ad3d..7a03b7f9f 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.h
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.h
> @@ -148,6 +148,9 @@ DECLARE_ACCESSOR(wpas_dbus_setter_fast_reauth);
>  DECLARE_ACCESSOR(wpas_dbus_getter_disconnect_reason);
>  DECLARE_ACCESSOR(wpas_dbus_getter_disassociate_reason);
>  DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
> +DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
> +DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
> +DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
>  DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
> diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
> index 83df04f39..a2b04716d 100644
> --- a/wpa_supplicant/notify.c
> +++ b/wpa_supplicant/notify.c
> @@ -149,6 +149,33 @@ void wpas_notify_assoc_status_code(struct
> wpa_supplicant *wpa_s)
>  }
>  
>  
> +void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
> +{
> +	if (wpa_s->p2p_mgmt)
> +		return;
> +
> +	wpas_dbus_signal_prop_changed(wpa_s,
> WPAS_DBUS_PROP_ROAM_TIME);
> +}
> +
> +
> +void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s)
> +{
> +	if (wpa_s->p2p_mgmt)
> +		return;
> +
> +	wpas_dbus_signal_prop_changed(wpa_s,
> WPAS_DBUS_PROP_ROAM_COMPLETE);
> +}
> +
> +
> +void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
> +{
> +	if (wpa_s->p2p_mgmt)
> +		return;
> +
> +	wpas_dbus_signal_prop_changed(wpa_s,
> WPAS_DBUS_PROP_SESSION_LENGTH);
> +}
> +
> +
>  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
>  {
>  	if (wpa_s->p2p_mgmt)
> diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
> index 3ca933c76..bde20e83d 100644
> --- a/wpa_supplicant/notify.h
> +++ b/wpa_supplicant/notify.h
> @@ -24,6 +24,9 @@ void wpas_notify_state_changed(struct
> wpa_supplicant *wpa_s,
>  			       enum wpa_states old_state);
>  void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
>  void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s);
> +void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
> +void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
> +void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
>  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
>  void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
>  void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
> diff --git a/wpa_supplicant/wpa_supplicant.c
> b/wpa_supplicant/wpa_supplicant.c
> index dcd787bec..df27c55ad 100644
> --- a/wpa_supplicant/wpa_supplicant.c
> +++ b/wpa_supplicant/wpa_supplicant.c
> @@ -839,6 +839,40 @@ void wpa_supplicant_set_state(struct
> wpa_supplicant *wpa_s,
>  		wpa_supplicant_state_txt(wpa_s->wpa_state),
>  		wpa_supplicant_state_txt(state));
>  
> +	if (state == WPA_AUTHENTICATING && wpa_s->wpa_state ==
> WPA_COMPLETED) {
> +		if (wpa_s->sme.prev_bssid_set &&
> +		    os_memcmp(wpa_s->sme.prev_bssid, wpa_s-
> >pending_bssid, ETH_ALEN) != 0) {
> +			os_get_reltime(&wpa_s->roam_start);
> +		}
> +	} else if (state == WPA_COMPLETED &&
> +		   os_reltime_initialized(&wpa_s->roam_start)) {
> +		os_reltime_age(&wpa_s->roam_start, &wpa_s-
> >roam_time);
> +		wpa_s->roam_start.sec = 0;
> +		wpa_s->roam_start.usec = 0;
> +		wpas_notify_auth_changed(wpa_s);
> +		wpas_notify_roam_time(wpa_s);
> +		wpas_notify_roam_complete(wpa_s);
> +	} else if (state == WPA_DISCONNECTED &&
> +		   os_reltime_initialized(&wpa_s->roam_start)) {
> +		wpa_s->roam_start.sec = 0;
> +		wpa_s->roam_start.usec = 0;
> +		wpa_s->roam_time.sec = 0;
> +		wpa_s->roam_time.usec = 0;
> +		wpas_notify_roam_complete(wpa_s);
> +	}
> +
> +	if (state == WPA_COMPLETED && wpa_s->wpa_state !=
> WPA_COMPLETED) {
> +		wpas_notify_auth_changed(wpa_s);
> +		os_get_reltime(&wpa_s->session_start);
> +	} else if (state != WPA_COMPLETED &&
> +		   wpa_s->wpa_state == WPA_COMPLETED &&
> +		   os_reltime_initialized(&wpa_s->session_start)) {
> +		os_reltime_age(&wpa_s->session_start, &wpa_s-
> >session_length);
> +		wpa_s->session_start.sec = 0;
> +		wpa_s->session_start.usec = 0;
> +		wpas_notify_session_length(wpa_s);
> +	}
> +
>  	if (state == WPA_INTERFACE_DISABLED) {
>  		/* Assure normal scan when interface is restored */
>  		wpa_s->normal_scans = 0;
> diff --git a/wpa_supplicant/wpa_supplicant_i.h
> b/wpa_supplicant/wpa_supplicant_i.h
> index 4d18177fb..a4d56b810 100644
> --- a/wpa_supplicant/wpa_supplicant_i.h
> +++ b/wpa_supplicant/wpa_supplicant_i.h
> @@ -492,6 +492,10 @@ struct wpa_supplicant {
>  	struct wpa_supplicant *next;
>  	struct l2_packet_data *l2;
>  	struct l2_packet_data *l2_br;
> +	struct os_reltime roam_start;
> +	struct os_reltime roam_time;
> +	struct os_reltime session_start;
> +	struct os_reltime session_length;
>  	unsigned char own_addr[ETH_ALEN];
>  	unsigned char perm_addr[ETH_ALEN];
>  	char ifname[100];


From dcbw at redhat.com  Fri May  4 07:47:10 2018
From: dcbw at redhat.com (Dan Williams)
Date: Fri, 04 May 2018 09:47:10 -0500
Subject: [PATCH] dbus: export BSS Transition Management status to dbus
In-Reply-To: <20180504010052.66020-1-matthewmwang@chromium.org>
References: <20180504010052.66020-1-matthewmwang@chromium.org>
Message-ID: <aab7cae4dad8c52464cc9f05990c56fe9ed56d14.camel@redhat.com>

On Thu, 2018-05-03 at 18:00 -0700, Matthew Wang wrote:
> Added new Interface properties "BSSTMStatus", which carries the
> status of
> the most recent BSS Transition Management request. This property will
> be
> logged in UMA to measure 802.11v success.
> 
> Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
> ---
>  doc/dbus.doxygen                        |  5 +++++
>  wpa_supplicant/dbus/dbus_new.c          |  9 +++++++++
>  wpa_supplicant/dbus/dbus_new.h          |  1 +
>  wpa_supplicant/dbus/dbus_new_handlers.c | 22 ++++++++++++++++++++++
>  wpa_supplicant/dbus/dbus_new_handlers.h |  1 +
>  wpa_supplicant/notify.c                 |  9 +++++++++
>  wpa_supplicant/notify.h                 |  1 +
>  wpa_supplicant/wnm_sta.c                |  4 ++++
>  wpa_supplicant/wpa_supplicant_i.h       |  1 +
>  9 files changed, 53 insertions(+)
> 
> diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
> index d3003b31d..cf5129474 100644
> --- a/doc/dbus.doxygen
> +++ b/doc/dbus.doxygen
> @@ -784,6 +784,11 @@ fi.w1.wpa_supplicant1.CreateInterface.
>  	<p>The most recent BSS session length in milliseconds.</p>
>        </li>
>  
> +      <li>
> +	<h3>BSSTMStatus - i - (read)</h3>
> +	<p>The most recent BSS Transition Management status
> code.</p>
> +      </li>

Is this ever going to be less than zero?  The enum won't be.

>        <li>
>  	<h3>EapolVersion - s - (read/write)</h3>
>  	<p>IEEE 802.1X/EAPOL version number</p>
> diff --git a/wpa_supplicant/dbus/dbus_new.c
> b/wpa_supplicant/dbus/dbus_new.c
> index 168e9baf6..2f4b2bf46 100644
> --- a/wpa_supplicant/dbus/dbus_new.c
> +++ b/wpa_supplicant/dbus/dbus_new.c
> @@ -2171,6 +2171,9 @@ void wpas_dbus_signal_prop_changed(struct
> wpa_supplicant *wpa_s,
>  	case WPAS_DBUS_PROP_SESSION_LENGTH:
>  		prop = "SessionLength";
>  		break;
> +	case WPAS_DBUS_PROP_BSS_TM_STATUS:
> +		prop = "BSSTMStatus";
> +		break;
>  	default:
>  		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property
> value %d",
>  			   __func__, property);
> @@ -2758,6 +2761,12 @@ static const struct wpa_dbus_property_desc
> wpas_dbus_bss_properties[] = {
>  	  NULL,
>  	  NULL
>  	},
> +	{
> +	  "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
> +	  wpas_dbus_getter_bss_tm_status,
> +	  NULL,
> +	  NULL
> +	},
>  	{ NULL, NULL, NULL, NULL, NULL, NULL }
>  };
>  
> diff --git a/wpa_supplicant/dbus/dbus_new.h
> b/wpa_supplicant/dbus/dbus_new.h
> index 08f4858b1..bec9a4153 100644
> --- a/wpa_supplicant/dbus/dbus_new.h
> +++ b/wpa_supplicant/dbus/dbus_new.h
> @@ -34,6 +34,7 @@ enum wpas_dbus_prop {
>  	WPAS_DBUS_PROP_ROAM_TIME,
>  	WPAS_DBUS_PROP_ROAM_COMPLETE,
>  	WPAS_DBUS_PROP_SESSION_LENGTH,
> +	WPAS_DBUS_PROP_BSS_TM_STATUS,
>  };
>  
>  enum wpas_dbus_bss_prop {
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c
> b/wpa_supplicant/dbus/dbus_new_handlers.c
> index 4e3412cdc..367d26d14 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.c
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.c
> @@ -3223,6 +3223,28 @@ dbus_bool_t wpas_dbus_getter_session_length(
>  }
>  
>  
> +/**
> + * wpas_dbus_getter_bss_tm_status - Get most BSS Transition
> Management request
> + * status code
> + * @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 "BSSTMStatus" property.
> + */
> +dbus_bool_t wpas_dbus_getter_bss_tm_status(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct wpa_supplicant *wpa_s = user_data;
> +	dbus_int32_t bss_tm_status = wpa_s->bss_tm_status;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_INT32,
> +						&bss_tm_status,
> error);
> +}
> +
> +
>  /**
>   * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
>   * @iter: Pointer to incoming dbus message iter
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h
> b/wpa_supplicant/dbus/dbus_new_handlers.h
> index 7a03b7f9f..25ab9991c 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.h
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.h
> @@ -151,6 +151,7 @@
> DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
>  DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
>  DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
>  DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
> +DECLARE_ACCESSOR(wpas_dbus_getter_bss_tm_status);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
>  DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
> diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
> index a2b04716d..b171e8e87 100644
> --- a/wpa_supplicant/notify.c
> +++ b/wpa_supplicant/notify.c
> @@ -176,6 +176,15 @@ void wpas_notify_session_length(struct
> wpa_supplicant *wpa_s)
>  }
>  
>  
> +void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
> +{
> +	if (wpa_s->p2p_mgmt)
> +		return;
> +
> +	wpas_dbus_signal_prop_changed(wpa_s,
> WPAS_DBUS_PROP_BSS_TM_STATUS);
> +}
> +
> +
>  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
>  {
>  	if (wpa_s->p2p_mgmt)
> diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
> index bde20e83d..9605785cf 100644
> --- a/wpa_supplicant/notify.h
> +++ b/wpa_supplicant/notify.h
> @@ -27,6 +27,7 @@ void wpas_notify_assoc_status_code(struct
> wpa_supplicant *wpa_s);
>  void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
>  void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
>  void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
> +void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
>  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
>  void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
>  void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
> diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
> index 7c410e730..1dbc90352 100644
> --- a/wpa_supplicant/wnm_sta.c
> +++ b/wpa_supplicant/wnm_sta.c
> @@ -20,6 +20,7 @@
>  #include "ctrl_iface.h"
>  #include "bss.h"
>  #include "wnm_sta.h"
> +#include "notify.h"
>  #include "hs20_supplicant.h"
>  
>  #define MAX_TFS_IE_LEN  1024
> @@ -938,6 +939,9 @@ static void wnm_send_bss_transition_mgmt_resp(
>  		return;
>  	}
>  
> +        wpa_s->bss_tm_status = status;
> +        wpas_notify_bss_tm_status(wpa_s);

Whitespace issues.

>  	wpabuf_put_u8(buf, WLAN_ACTION_WNM);
>  	wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_RESP);
>  	wpabuf_put_u8(buf, dialog_token);
> diff --git a/wpa_supplicant/wpa_supplicant_i.h
> b/wpa_supplicant/wpa_supplicant_i.h
> index a4d56b810..70da2a4b1 100644
> --- a/wpa_supplicant/wpa_supplicant_i.h
> +++ b/wpa_supplicant/wpa_supplicant_i.h
> @@ -1059,6 +1059,7 @@ struct wpa_supplicant {
>  	struct neighbor_report *wnm_neighbor_report_elements;
>  	struct os_reltime wnm_cand_valid_until;
>  	u8 wnm_cand_from_bss[ETH_ALEN];
> +        enum bss_trans_mgmt_status_code bss_tm_status;

Whitespace issues here too.

Dan

>  #ifdef CONFIG_MBO
>  	unsigned int wnm_mbo_trans_reason_present:1;
>  	u8 wnm_mbo_transition_reason;


From michal.ruza at gmail.com  Fri May  4 06:59:27 2018
From: michal.ruza at gmail.com (=?UTF-8?B?TWljaGFsIFLFr8W+acSNa2E=?=)
Date: Fri, 4 May 2018 15:59:27 +0200
Subject: Dealing with encrypted message 4 of the WPA 4-way handshake
In-Reply-To: <e96cc4fd-49da-1663-3780-2e77dab1cbba@gmail.com>
References: <e96cc4fd-49da-1663-3780-2e77dab1cbba@gmail.com>
Message-ID: <9eb483d9-a91c-ad1a-e5c0-802157beafde@gmail.com>

Hi,
I'm having problems connecting to wpa_supplicant/hostap running on linux
from newer Android devices (Android 6.0 and above).
The problem is that the newer Android devices encrypt (with rare
exceptions) the message 4 of the WPA 4-way handshake. Such message is
likely dropped by the linux kernel as it cannot be decrypted, in
consequence the wpa_supplicant does not consider the handshake to be
completed successfully and after a couple of re-sends of the message 3
it disassociates the Android device.

I've logged a bug report with Fedora [1] where I included a patch
providing a best effort solution which I don't consider to be suitable
for inclusion in the wpa_supplicant as it is racy and as a consequence
can be ineffective on slower hardware. The solution it provides is to
install the PTK key as soon as the message 3 is sent by the
wpa_supplicant, so that the message 4 can be decrypted if STA encrypts
it. Additionally if there is a need to re-send the message 3, the key is
uninstalled before the re-send and installed again afterwards (this is
totally untested and may likely interfere with frame sequence numbers).
Nevertheless in the happy case scenario (no retransmissions) it works.
Further in the bug report I envision a better, race-free solution which
would install the PTK even before sending the message 3 but despite that
it would then send the message 3 (including its possible re-sends)
unencrypted. The problem is I don't know how to achieve that: I don't
see a way to send an unencrypted frame once the PTK is installed. I tend
to think that a recent kernel patch [2] is supposed to address this
exact issue.

What's your opinion on the best effort solution provided in the patch?
Would it make sense to include it the wpa_supplicant?
Does the race-free solution make sense? (Is so could it be implemented
by other means than those introduced in [2]? I.e. is there some other
way to send an unencrypted frame once the PTK is installed?)

Cheers,
Michal

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1571256
[2]
https://github.com/torvalds/linux/commit/2576a9ace47eba28a682d249d1d6402f891808c9


From dcbw at redhat.com  Fri May  4 10:58:19 2018
From: dcbw at redhat.com (Dan Williams)
Date: Fri, 04 May 2018 12:58:19 -0500
Subject: [PATCH] dbus: export roam time, roam complete, and session
 length to dbus
In-Reply-To: <CAAooHFeNdE9JTJe_RRzCJ2mFfG2=TubKbgeRmt+pqBqpmW9E1g@mail.gmail.com>
References: <20180503233228.46852-1-matthewmwang@chromium.org>
 <7f094e40cf8395816b36c7731220e2243f5d2d0b.camel@redhat.com>
 <CAAooHFeNdE9JTJe_RRzCJ2mFfG2=TubKbgeRmt+pqBqpmW9E1g@mail.gmail.com>
Message-ID: <d298094789641f53740a4a9269cb577281310e41.camel@redhat.com>

On Fri, 2018-05-04 at 17:08 +0000, Matthew Wang wrote:
> No reason, should I resend the patch?

Yeah, if you could.

Dan

> On Fri, May 4, 2018 at 7:43 AM Dan Williams <dcbw at redhat.com> wrote:
> 
> > On Thu, 2018-05-03 at 16:32 -0700, Matthew Wang wrote:
> > > Added new Interface properties "RoamTime", "RoamComplete", and
> > > "SessionLength".
> > > 
> > > "RoamTime" carries the roam time of the most recent roam in
> > > milliseconds.
> > > "RoamComplete" carries True or False corresponding to the success
> > > status of the
> > > most recent roam.
> > > "SessionLength" carries the number of milliseconds corresponding
> > > to
> > > how long
> > > the connection to the last AP was before a roam or disconnect
> > > happened.
> > > 
> > > These properties will all be logged in UMA to compare FT vs non-
> > > FT
> > > network
> > > behaviors.
> > > 
> > > Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
> > > ---
> > >  doc/dbus.doxygen                        | 15 ++++++
> > >  wpa_supplicant/dbus/dbus_new.c          | 27 ++++++++++
> > >  wpa_supplicant/dbus/dbus_new.h          |  3 ++
> > >  wpa_supplicant/dbus/dbus_new_handlers.c | 65
> > > +++++++++++++++++++++++++
> > >  wpa_supplicant/dbus/dbus_new_handlers.h |  3 ++
> > >  wpa_supplicant/notify.c                 | 27 ++++++++++
> > >  wpa_supplicant/notify.h                 |  3 ++
> > >  wpa_supplicant/wpa_supplicant.c         | 34 +++++++++++++
> > >  wpa_supplicant/wpa_supplicant_i.h       |  4 ++
> > >  9 files changed, 181 insertions(+)
> > > 
> > > diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
> > > index 2ca40ae9b..d3003b31d 100644
> > > --- a/doc/dbus.doxygen
> > > +++ b/doc/dbus.doxygen
> > > @@ -769,6 +769,21 @@ fi.w1.wpa_supplicant1.CreateInterface.
> > >       <p>The most recent IEEE 802.11 status code for association
> > > rejection.</p>
> > >        </li>
> > > 
> > > +      <li>
> > > +     <h3>RoamTime - i - (read)</h3>
> > > +     <p>The most recent roam time in milliseconds.</p>
> > > +      </li>
> > 
> > Any reason to have RoamTime and SessionLength be int, rather than
> > uint?
> >  Are they ever going to be less than zero?
> > 
> > Dan
> > 
> > > +      <li>
> > > +     <h3>RoamComplete - b - (read)</h3>
> > > +     <p>The most recent roam success or failure.</p>
> > > +      </li>
> > > +
> > > +      <li>
> > > +     <h3>SessionLength - i - (read)</h3>
> > > +     <p>The most recent BSS session length in milliseconds.</p>
> > > +      </li>
> > > +
> > >        <li>
> > >       <h3>EapolVersion - s - (read/write)</h3>
> > >       <p>IEEE 802.1X/EAPOL version number</p>
> > > diff --git a/wpa_supplicant/dbus/dbus_new.c
> > > b/wpa_supplicant/dbus/dbus_new.c
> > > index e0f16bbda..168e9baf6 100644
> > > --- a/wpa_supplicant/dbus/dbus_new.c
> > > +++ b/wpa_supplicant/dbus/dbus_new.c
> > > @@ -2162,6 +2162,15 @@ void wpas_dbus_signal_prop_changed(struct
> > > wpa_supplicant *wpa_s,
> > >               prop = "AssocStatusCode";
> > >               flush = TRUE;
> > >               break;
> > > +     case WPAS_DBUS_PROP_ROAM_TIME:
> > > +             prop = "RoamTime";
> > > +             break;
> > > +     case WPAS_DBUS_PROP_ROAM_COMPLETE:
> > > +             prop = "RoamComplete";
> > > +             break;
> > > +     case WPAS_DBUS_PROP_SESSION_LENGTH:
> > > +             prop = "SessionLength";
> > > +             break;
> > >       default:
> > >               wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property
> > > value %d",
> > >                          __func__, property);
> > > @@ -2731,6 +2740,24 @@ static const struct wpa_dbus_property_desc
> > > wpas_dbus_bss_properties[] = {
> > >         NULL,
> > >         NULL
> > >       },
> > > +     {
> > > +       "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
> > > +       wpas_dbus_getter_roam_time,
> > > +       NULL,
> > > +       NULL
> > > +     },
> > > +     {
> > > +       "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
> > > +       wpas_dbus_getter_roam_complete,
> > > +       NULL,
> > > +       NULL
> > > +     },
> > > +     {
> > > +       "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
> > > +       wpas_dbus_getter_session_length,
> > > +       NULL,
> > > +       NULL
> > > +     },
> > >       { NULL, NULL, NULL, NULL, NULL, NULL }
> > >  };
> > > 
> > > diff --git a/wpa_supplicant/dbus/dbus_new.h
> > > b/wpa_supplicant/dbus/dbus_new.h
> > > index e68acb7a1..08f4858b1 100644
> > > --- a/wpa_supplicant/dbus/dbus_new.h
> > > +++ b/wpa_supplicant/dbus/dbus_new.h
> > > @@ -31,6 +31,9 @@ enum wpas_dbus_prop {
> > >       WPAS_DBUS_PROP_BSSS,
> > >       WPAS_DBUS_PROP_DISCONNECT_REASON,
> > >       WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
> > > +     WPAS_DBUS_PROP_ROAM_TIME,
> > > +     WPAS_DBUS_PROP_ROAM_COMPLETE,
> > > +     WPAS_DBUS_PROP_SESSION_LENGTH,
> > >  };
> > > 
> > >  enum wpas_dbus_bss_prop {
> > > diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c
> > > b/wpa_supplicant/dbus/dbus_new_handlers.c
> > > index a3c98fadd..4e3412cdc 100644
> > > --- a/wpa_supplicant/dbus/dbus_new_handlers.c
> > > +++ b/wpa_supplicant/dbus/dbus_new_handlers.c
> > > @@ -3158,6 +3158,71 @@ dbus_bool_t
> > > wpas_dbus_getter_assoc_status_code(
> > >  }
> > > 
> > > 
> > > +/**
> > > + * wpas_dbus_getter_roam_time - Get most recent roam time
> > > + * @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 "RoamTime" property.
> > > + */
> > > +dbus_bool_t wpas_dbus_getter_roam_time(
> > > +     const struct wpa_dbus_property_desc *property_desc,
> > > +     DBusMessageIter *iter, DBusError *error, void *user_data)
> > > +{
> > > +     struct wpa_supplicant *wpa_s = user_data;
> > > +     dbus_int32_t roam_time = wpa_s->roam_time.sec * 1000 +
> > > +                              wpa_s->roam_time.usec / 1000;
> > > +
> > > +     return wpas_dbus_simple_property_getter(iter,
> > > DBUS_TYPE_INT32,
> > > +                                             &roam_time, error);
> > > +}
> > > +
> > > +/**
> > > + * wpas_dbus_getter_roam_complete - Get most recent roam success
> > > or
> > > failure
> > > + * @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 "RoamComplete" property.
> > > + */
> > > +dbus_bool_t wpas_dbus_getter_roam_complete(
> > > +     const struct wpa_dbus_property_desc *property_desc,
> > > +     DBusMessageIter *iter, DBusError *error, void *user_data)
> > > +{
> > > +     struct wpa_supplicant *wpa_s = user_data;
> > > +     dbus_bool_t roam_complete = os_reltime_initialized(&wpa_s-
> > > > roam_time) ?
> > > 
> > > +                                 TRUE : FALSE;
> > > +
> > > +     return wpas_dbus_simple_property_getter(iter,
> > > DBUS_TYPE_BOOLEAN,
> > > +                                             &roam_complete,
> > > error);
> > > +}
> > > +
> > > +
> > > +/**
> > > + * wpas_dbus_getter_session_length - Get most recent BSS session
> > > length
> > > + * @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 "SessionLength" property.
> > > + */
> > > +dbus_bool_t wpas_dbus_getter_session_length(
> > > +     const struct wpa_dbus_property_desc *property_desc,
> > > +     DBusMessageIter *iter, DBusError *error, void *user_data)
> > > +{
> > > +     struct wpa_supplicant *wpa_s = user_data;
> > > +     dbus_int32_t session_length = wpa_s->session_length.sec *
> > > 1000 +
> > > +                                   wpa_s->session_length.usec /
> > > 1000;
> > > +
> > > +     return wpas_dbus_simple_property_getter(iter,
> > > DBUS_TYPE_INT32,
> > > +                                             &session_length,
> > > error);
> > > +}
> > > +
> > > +
> > >  /**
> > >   * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration
> > > age
> > >   * @iter: Pointer to incoming dbus message iter
> > > diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h
> > > b/wpa_supplicant/dbus/dbus_new_handlers.h
> > > index 26652ad3d..7a03b7f9f 100644
> > > --- a/wpa_supplicant/dbus/dbus_new_handlers.h
> > > +++ b/wpa_supplicant/dbus/dbus_new_handlers.h
> > > @@ -148,6 +148,9 @@
> > > DECLARE_ACCESSOR(wpas_dbus_setter_fast_reauth);
> > >  DECLARE_ACCESSOR(wpas_dbus_getter_disconnect_reason);
> > >  DECLARE_ACCESSOR(wpas_dbus_getter_disassociate_reason);
> > >  DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
> > > +DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
> > > +DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
> > > +DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
> > >  DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
> > >  DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
> > >  DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
> > > diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
> > > index 83df04f39..a2b04716d 100644
> > > --- a/wpa_supplicant/notify.c
> > > +++ b/wpa_supplicant/notify.c
> > > @@ -149,6 +149,33 @@ void wpas_notify_assoc_status_code(struct
> > > wpa_supplicant *wpa_s)
> > >  }
> > > 
> > > 
> > > +void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
> > > +{
> > > +     if (wpa_s->p2p_mgmt)
> > > +             return;
> > > +
> > > +     wpas_dbus_signal_prop_changed(wpa_s,
> > > WPAS_DBUS_PROP_ROAM_TIME);
> > > +}
> > > +
> > > +
> > > +void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s)
> > > +{
> > > +     if (wpa_s->p2p_mgmt)
> > > +             return;
> > > +
> > > +     wpas_dbus_signal_prop_changed(wpa_s,
> > > WPAS_DBUS_PROP_ROAM_COMPLETE);
> > > +}
> > > +
> > > +
> > > +void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
> > > +{
> > > +     if (wpa_s->p2p_mgmt)
> > > +             return;
> > > +
> > > +     wpas_dbus_signal_prop_changed(wpa_s,
> > > WPAS_DBUS_PROP_SESSION_LENGTH);
> > > +}
> > > +
> > > +
> > >  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
> > >  {
> > >       if (wpa_s->p2p_mgmt)
> > > diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
> > > index 3ca933c76..bde20e83d 100644
> > > --- a/wpa_supplicant/notify.h
> > > +++ b/wpa_supplicant/notify.h
> > > @@ -24,6 +24,9 @@ void wpas_notify_state_changed(struct
> > > wpa_supplicant *wpa_s,
> > >                              enum wpa_states old_state);
> > >  void wpas_notify_disconnect_reason(struct wpa_supplicant
> > > *wpa_s);
> > >  void wpas_notify_assoc_status_code(struct wpa_supplicant
> > > *wpa_s);
> > > +void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
> > > +void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
> > > +void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
> > >  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
> > >  void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
> > >  void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
> > > diff --git a/wpa_supplicant/wpa_supplicant.c
> > > b/wpa_supplicant/wpa_supplicant.c
> > > index dcd787bec..df27c55ad 100644
> > > --- a/wpa_supplicant/wpa_supplicant.c
> > > +++ b/wpa_supplicant/wpa_supplicant.c
> > > @@ -839,6 +839,40 @@ void wpa_supplicant_set_state(struct
> > > wpa_supplicant *wpa_s,
> > >               wpa_supplicant_state_txt(wpa_s->wpa_state),
> > >               wpa_supplicant_state_txt(state));
> > > 
> > > +     if (state == WPA_AUTHENTICATING && wpa_s->wpa_state ==
> > > WPA_COMPLETED) {
> > > +             if (wpa_s->sme.prev_bssid_set &&
> > > +                 os_memcmp(wpa_s->sme.prev_bssid, wpa_s-
> > > > pending_bssid, ETH_ALEN) != 0) {
> > > 
> > > +                     os_get_reltime(&wpa_s->roam_start);
> > > +             }
> > > +     } else if (state == WPA_COMPLETED &&
> > > +                os_reltime_initialized(&wpa_s->roam_start)) {
> > > +             os_reltime_age(&wpa_s->roam_start, &wpa_s-
> > > > roam_time);
> > > 
> > > +             wpa_s->roam_start.sec = 0;
> > > +             wpa_s->roam_start.usec = 0;
> > > +             wpas_notify_auth_changed(wpa_s);
> > > +             wpas_notify_roam_time(wpa_s);
> > > +             wpas_notify_roam_complete(wpa_s);
> > > +     } else if (state == WPA_DISCONNECTED &&
> > > +                os_reltime_initialized(&wpa_s->roam_start)) {
> > > +             wpa_s->roam_start.sec = 0;
> > > +             wpa_s->roam_start.usec = 0;
> > > +             wpa_s->roam_time.sec = 0;
> > > +             wpa_s->roam_time.usec = 0;
> > > +             wpas_notify_roam_complete(wpa_s);
> > > +     }
> > > +
> > > +     if (state == WPA_COMPLETED && wpa_s->wpa_state !=
> > > WPA_COMPLETED) {
> > > +             wpas_notify_auth_changed(wpa_s);
> > > +             os_get_reltime(&wpa_s->session_start);
> > > +     } else if (state != WPA_COMPLETED &&
> > > +                wpa_s->wpa_state == WPA_COMPLETED &&
> > > +                os_reltime_initialized(&wpa_s->session_start)) {
> > > +             os_reltime_age(&wpa_s->session_start, &wpa_s-
> > > > session_length);
> > > 
> > > +             wpa_s->session_start.sec = 0;
> > > +             wpa_s->session_start.usec = 0;
> > > +             wpas_notify_session_length(wpa_s);
> > > +     }
> > > +
> > >       if (state == WPA_INTERFACE_DISABLED) {
> > >               /* Assure normal scan when interface is restored */
> > >               wpa_s->normal_scans = 0;
> > > diff --git a/wpa_supplicant/wpa_supplicant_i.h
> > > b/wpa_supplicant/wpa_supplicant_i.h
> > > index 4d18177fb..a4d56b810 100644
> > > --- a/wpa_supplicant/wpa_supplicant_i.h
> > > +++ b/wpa_supplicant/wpa_supplicant_i.h
> > > @@ -492,6 +492,10 @@ struct wpa_supplicant {
> > >       struct wpa_supplicant *next;
> > >       struct l2_packet_data *l2;
> > >       struct l2_packet_data *l2_br;
> > > +     struct os_reltime roam_start;
> > > +     struct os_reltime roam_time;
> > > +     struct os_reltime session_start;
> > > +     struct os_reltime session_length;
> > >       unsigned char own_addr[ETH_ALEN];
> > >       unsigned char perm_addr[ETH_ALEN];
> > >       char ifname[100];


From masashi.honma at gmail.com  Fri May  4 18:21:00 2018
From: masashi.honma at gmail.com (Masashi Honma)
Date: Sat, 5 May 2018 10:21:00 +0900
Subject: [PATCH v3 00/15] mesh: enable DFS channels in mesh mode
In-Reply-To: <cover.1524027184.git.peter.oh@bowerswilkins.com>
References: <cover.1524027184.git.peter.oh@bowerswilkins.com>
Message-ID: <f30a7e1c-f78e-5a9b-c2ab-0fd2f691cdd8@gmail.com>

On 2018/04/18 13:54, peter.oh at bowerswilkins.com wrote:
> From: Peter Oh <peter.oh at bowerswilkins.com>
> 
> This patchset enables DFS channels in mesh mode along with
> CAC and channel switch.
> It's been verified that works for non-dfs channels, dfs channels,
> w/wo encryption (none and SAE), radar detection, channel switch,
> and mesh re-association after channel switch.
> Only left area to cover is in the case when multiple mesh points
> detect radar at the same time, but they select different channels.
> To cover the case I think we need a private patch for it,
> because current 802.11s standard does not address it how to handle.
> 
> * v2: corrected wrong sender's email
> * v3: rebased on top of "mesh: Properly handle sae_password"
>        fix compiler warnings on unused variables and parentheses

It looks need to be added notifications like this.

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 5a0d781..ba9d7d7 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -637,6 +637,17 @@ static unsigned int dfs_get_cac_time(struct 
hostapd_iface *iface,
  }


+static void *get_message_ctx(struct hostapd_iface *iface)
+{
+#ifdef CONFIG_MESH
+       if (iface->mconf)
+               return iface->owner;
+#endif /* CONFIG_MESH */
+
+       return iface->bss[0]->msg_ctx;
+}
+
+
  /*
   * Main DFS handler
   * 1 - continue channel/ap setup
@@ -719,7 +730,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
         /* Finally start CAC */
         hostapd_set_state(iface, HAPD_IFACE_DFS);
         wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq);
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
                 "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, 
seg1=%d, cac_time=%ds",
                 iface->freq,
                 iface->conf->channel, iface->conf->secondary_channel,
@@ -768,7 +779,7 @@ int hostapd_dfs_complete_cac(struct hostapd_iface 
*iface, int success, int freq,
                              int ht_enabled, int chan_offset, int 
chan_width,
                              int cf1, int cf2)
  {
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_COMPLETED
                 "success=%d freq=%d ht_enabled=%d chan_offset=%d 
chan_width=%d cf1=%d cf2=%d",
                 success, freq, ht_enabled, chan_offset, chan_width, 
cf1, cf2);

@@ -810,7 +821,7 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface 
*iface, int freq,
                                 int ht_enabled, int chan_offset, int 
chan_width,
                                 int cf1, int cf2)
  {
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
                 "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d 
cf1=%d cf2=%d",
                 freq, ht_enabled, chan_offset, chan_width, cf1, cf2);

@@ -848,7 +859,7 @@ static int 
hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)

         wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
                    channel->chan);
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
                 "freq=%d chan=%d sec_chan=%d", channel->freq,
                 channel->chan, secondary_channel);

@@ -935,7 +946,7 @@ static int hostapd_dfs_start_channel_switch(struct 
hostapd_iface *iface)

         wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
                    channel->chan);
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
                 "freq=%d chan=%d sec_chan=%d", channel->freq,
                 channel->chan, secondary_channel);

@@ -997,7 +1008,7 @@ int hostapd_dfs_radar_detected(struct hostapd_iface 
*iface, int freq,
  {
         int res;

-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_RADAR_DETECTED
                 "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d 
cf1=%d cf2=%d",
                 freq, ht_enabled, chan_offset, chan_width, cf1, cf2);

@@ -1028,7 +1039,7 @@ int hostapd_dfs_nop_finished(struct hostapd_iface 
*iface, int freq,
                              int ht_enabled, int chan_offset, int 
chan_width,
                              int cf1, int cf2)
  {
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NOP_FINISHED
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NOP_FINISHED
                 "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d 
cf1=%d cf2=%d",
                 freq, ht_enabled, chan_offset, chan_width, cf1, cf2);

@@ -1078,7 +1089,7 @@ int hostapd_dfs_start_cac(struct hostapd_iface 
*iface, int freq,
                           int ht_enabled, int chan_offset, int chan_width,
                           int cf1, int cf2)
  {
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
+       wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
                 "freq=%d chan=%d chan_offset=%d width=%d seg0=%d "
                 "seg1=%d cac_time=%ds",
                 freq, (freq - 5000) / 5, chan_offset, chan_width, cf1, 
cf2, 60);


diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 6524a53..edf1c89 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3818,7 +3818,7 @@ static void wpas_event_dfs_cac_finished(struct 
wpa_supplicant *wpa_s,
                                         struct dfs_event *radar)
  {
  #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-       if (wpa_s->ap_iface) {
+       if (wpa_s->ap_iface || wpa_s->ifmsh) {
                 wpas_ap_event_dfs_cac_finished(wpa_s, radar);
         } else
  #endif /* NEED_AP_MLME && CONFIG_AP */


And a memory leak should be fixed like this.


diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 67519fe..ca62b1a 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -439,6 +439,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant 
*wpa_s,

         if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency 
|| !params) {
                 ret = -ENOENT;
+               os_free(params);
                 goto out;
         }


After these fixes, I could pass this test case.

def test_wpas_mesh_open_dfs(dev, apdev):
     """wpa_supplicant open MESH network with DFS"""
     try:
         _test_wpas_mesh_open_dfs(dev, apdev)
     finally:
         set_country("00")

def _test_wpas_mesh_open_dfs(dev, apdev):
     set_country("US")
     dev[0].request("SET country US")
     check_mesh_support(dev[0])
     add_open_mesh_network(dev[0], freq="5260", basic_rates="60 120 240",
                           disable_ht40=True)

     ev = dev[0].wait_event(["DFS-CAC-START"], timeout=5)
     if ev is None:
         raise Exception("CAC did not start")

     check_mesh_group_added(dev[0])

     ev = dev[0].wait_event(["DFS-CAC-COMPLETED"], timeout=70)
     if ev is None:
         raise Exception("CAC did not complete")
     if "success=1" not in ev:
         raise Exception("CAC failed")
     if "freq=5260" not in ev:
         raise Exception("Unexpected DFS freq result")

     dev[0].mesh_group_remove()
     check_mesh_group_removed(dev[0])
     dev[0].dump_monitor()



Regards,
Masashi Honma.


From matthewmwang at chromium.org  Fri May  4 11:16:02 2018
From: matthewmwang at chromium.org (Matthew Wang)
Date: Fri,  4 May 2018 11:16:02 -0700
Subject: [PATCH RESEND] dbus: export roam time, roam complete, and session
 length to dbus
Message-ID: <20180504181602.34764-1-matthewmwang@chromium.org>

Added new Interface properties "RoamTime", "RoamComplete", and "SessionLength".

"RoamTime" carries the roam time of the most recent roam in milliseconds.
"RoamComplete" carries True or False corresponding to the success status of the
most recent roam.
"SessionLength" carries the number of milliseconds corresponding to how long
the connection to the last AP was before a roam or disconnect happened.

These properties will all be logged in UMA to compare FT vs non-FT network
behaviors.

Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
---
 doc/dbus.doxygen                        | 15 ++++++
 wpa_supplicant/dbus/dbus_new.c          | 27 ++++++++++
 wpa_supplicant/dbus/dbus_new.h          |  3 ++
 wpa_supplicant/dbus/dbus_new_handlers.c | 65 +++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  3 ++
 wpa_supplicant/notify.c                 | 27 ++++++++++
 wpa_supplicant/notify.h                 |  3 ++
 wpa_supplicant/wpa_supplicant.c         | 34 +++++++++++++
 wpa_supplicant/wpa_supplicant_i.h       |  4 ++
 9 files changed, 181 insertions(+)

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index 2ca40ae9b..64d2d0985 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -769,6 +769,21 @@ fi.w1.wpa_supplicant1.CreateInterface.
 	<p>The most recent IEEE 802.11 status code for association rejection.</p>
       </li>
 
+      <li>
+	<h3>RoamTime - u - (read)</h3>
+	<p>The most recent roam time in milliseconds.</p>
+      </li>
+
+      <li>
+	<h3>RoamComplete - b - (read)</h3>
+	<p>The most recent roam success or failure.</p>
+      </li>
+
+      <li>
+	<h3>SessionLength - u - (read)</h3>
+	<p>The most recent BSS session length in milliseconds.</p>
+      </li>
+
       <li>
 	<h3>EapolVersion - s - (read/write)</h3>
 	<p>IEEE 802.1X/EAPOL version number</p>
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index e0f16bbda..a50c7a540 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2162,6 +2162,15 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
 		prop = "AssocStatusCode";
 		flush = TRUE;
 		break;
+	case WPAS_DBUS_PROP_ROAM_TIME:
+		prop = "RoamTime";
+		break;
+	case WPAS_DBUS_PROP_ROAM_COMPLETE:
+		prop = "RoamComplete";
+		break;
+	case WPAS_DBUS_PROP_SESSION_LENGTH:
+		prop = "SessionLength";
+		break;
 	default:
 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
 			   __func__, property);
@@ -2731,6 +2740,24 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
 	  NULL,
 	  NULL
 	},
+	{
+	  "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
+	  wpas_dbus_getter_roam_time,
+	  NULL,
+	  NULL
+	},
+	{
+	  "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
+	  wpas_dbus_getter_roam_complete,
+	  NULL,
+	  NULL
+	},
+	{
+	  "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
+	  wpas_dbus_getter_session_length,
+	  NULL,
+	  NULL
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index e68acb7a1..08f4858b1 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -31,6 +31,9 @@ enum wpas_dbus_prop {
 	WPAS_DBUS_PROP_BSSS,
 	WPAS_DBUS_PROP_DISCONNECT_REASON,
 	WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
+	WPAS_DBUS_PROP_ROAM_TIME,
+	WPAS_DBUS_PROP_ROAM_COMPLETE,
+	WPAS_DBUS_PROP_SESSION_LENGTH,
 };
 
 enum wpas_dbus_bss_prop {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index a3c98fadd..e84acf230 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3158,6 +3158,71 @@ dbus_bool_t wpas_dbus_getter_assoc_status_code(
 }
 
 
+/**
+ * wpas_dbus_getter_roam_time - Get most recent roam time
+ * @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 "RoamTime" property.
+ */
+dbus_bool_t wpas_dbus_getter_roam_time(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_uint32_t roam_time = wpa_s->roam_time.sec * 1000 +
+				  wpa_s->roam_time.usec / 1000;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+						&roam_time, error);
+}
+
+/**
+ * wpas_dbus_getter_roam_complete - Get most recent roam success or failure
+ * @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 "RoamComplete" property.
+ */
+dbus_bool_t wpas_dbus_getter_roam_complete(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_bool_t roam_complete = os_reltime_initialized(&wpa_s->roam_time) ?
+				    TRUE : FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&roam_complete, error);
+}
+
+
+/**
+ * wpas_dbus_getter_session_length - Get most recent BSS session length
+ * @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 "SessionLength" property.
+ */
+dbus_bool_t wpas_dbus_getter_session_length(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_uint32_t session_length = wpa_s->session_length.sec * 1000 +
+				       wpa_s->session_length.usec / 1000;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+						&session_length, error);
+}
+
+
 /**
  * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
  * @iter: Pointer to incoming dbus message iter
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 26652ad3d..7a03b7f9f 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -148,6 +148,9 @@ DECLARE_ACCESSOR(wpas_dbus_setter_fast_reauth);
 DECLARE_ACCESSOR(wpas_dbus_getter_disconnect_reason);
 DECLARE_ACCESSOR(wpas_dbus_getter_disassociate_reason);
 DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
+DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
+DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
+DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 83df04f39..a2b04716d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -149,6 +149,33 @@ void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s)
 }
 
 
+void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_TIME);
+}
+
+
+void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_COMPLETE);
+}
+
+
+void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SESSION_LENGTH);
+}
+
+
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->p2p_mgmt)
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 3ca933c76..bde20e83d 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -24,6 +24,9 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
 			       enum wpa_states old_state);
 void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
 void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s);
+void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
+void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
+void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index dcd787bec..df27c55ad 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -839,6 +839,40 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 		wpa_supplicant_state_txt(wpa_s->wpa_state),
 		wpa_supplicant_state_txt(state));
 
+	if (state == WPA_AUTHENTICATING && wpa_s->wpa_state == WPA_COMPLETED) {
+		if (wpa_s->sme.prev_bssid_set &&
+		    os_memcmp(wpa_s->sme.prev_bssid, wpa_s->pending_bssid, ETH_ALEN) != 0) {
+			os_get_reltime(&wpa_s->roam_start);
+		}
+	} else if (state == WPA_COMPLETED &&
+		   os_reltime_initialized(&wpa_s->roam_start)) {
+		os_reltime_age(&wpa_s->roam_start, &wpa_s->roam_time);
+		wpa_s->roam_start.sec = 0;
+		wpa_s->roam_start.usec = 0;
+		wpas_notify_auth_changed(wpa_s);
+		wpas_notify_roam_time(wpa_s);
+		wpas_notify_roam_complete(wpa_s);
+	} else if (state == WPA_DISCONNECTED &&
+		   os_reltime_initialized(&wpa_s->roam_start)) {
+		wpa_s->roam_start.sec = 0;
+		wpa_s->roam_start.usec = 0;
+		wpa_s->roam_time.sec = 0;
+		wpa_s->roam_time.usec = 0;
+		wpas_notify_roam_complete(wpa_s);
+	}
+
+	if (state == WPA_COMPLETED && wpa_s->wpa_state != WPA_COMPLETED) {
+		wpas_notify_auth_changed(wpa_s);
+		os_get_reltime(&wpa_s->session_start);
+	} else if (state != WPA_COMPLETED &&
+		   wpa_s->wpa_state == WPA_COMPLETED &&
+		   os_reltime_initialized(&wpa_s->session_start)) {
+		os_reltime_age(&wpa_s->session_start, &wpa_s->session_length);
+		wpa_s->session_start.sec = 0;
+		wpa_s->session_start.usec = 0;
+		wpas_notify_session_length(wpa_s);
+	}
+
 	if (state == WPA_INTERFACE_DISABLED) {
 		/* Assure normal scan when interface is restored */
 		wpa_s->normal_scans = 0;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 4d18177fb..a4d56b810 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -492,6 +492,10 @@ struct wpa_supplicant {
 	struct wpa_supplicant *next;
 	struct l2_packet_data *l2;
 	struct l2_packet_data *l2_br;
+	struct os_reltime roam_start;
+	struct os_reltime roam_time;
+	struct os_reltime session_start;
+	struct os_reltime session_length;
 	unsigned char own_addr[ETH_ALEN];
 	unsigned char perm_addr[ETH_ALEN];
 	char ifname[100];
-- 
2.17.0.441.gb46fe60e1d-goog



From matthewmwang at chromium.org  Fri May  4 11:16:18 2018
From: matthewmwang at chromium.org (Matthew Wang)
Date: Fri,  4 May 2018 11:16:18 -0700
Subject: [PATCH RESEND] dbus: export BSS Transition Management status to dbus
Message-ID: <20180504181618.35256-1-matthewmwang@chromium.org>

Added new Interface properties "BSSTMStatus", which carries the status of
the most recent BSS Transition Management request. This property will be
logged in UMA to measure 802.11v success.

Signed-off-by: Matthew Wang <matthewmwang at chromium.org>
---
 doc/dbus.doxygen                        |  5 +++++
 wpa_supplicant/dbus/dbus_new.c          |  9 +++++++++
 wpa_supplicant/dbus/dbus_new.h          |  1 +
 wpa_supplicant/dbus/dbus_new_handlers.c | 22 ++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  1 +
 wpa_supplicant/notify.c                 |  9 +++++++++
 wpa_supplicant/notify.h                 |  1 +
 wpa_supplicant/wnm_sta.c                |  4 ++++
 wpa_supplicant/wpa_supplicant_i.h       |  1 +
 9 files changed, 53 insertions(+)

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index 64d2d0985..531272341 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -784,6 +784,11 @@ fi.w1.wpa_supplicant1.CreateInterface.
 	<p>The most recent BSS session length in milliseconds.</p>
       </li>
 
+      <li>
+	<h3>BSSTMStatus - u - (read)</h3>
+	<p>The most recent BSS Transition Management status code.</p>
+      </li>
+
       <li>
 	<h3>EapolVersion - s - (read/write)</h3>
 	<p>IEEE 802.1X/EAPOL version number</p>
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index a50c7a540..fb0dc5923 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2171,6 +2171,9 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
 	case WPAS_DBUS_PROP_SESSION_LENGTH:
 		prop = "SessionLength";
 		break;
+	case WPAS_DBUS_PROP_BSS_TM_STATUS:
+		prop = "BSSTMStatus";
+		break;
 	default:
 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
 			   __func__, property);
@@ -2758,6 +2761,12 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
 	  NULL,
 	  NULL
 	},
+	{
+	  "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
+	  wpas_dbus_getter_bss_tm_status,
+	  NULL,
+	  NULL
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 08f4858b1..bec9a4153 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -34,6 +34,7 @@ enum wpas_dbus_prop {
 	WPAS_DBUS_PROP_ROAM_TIME,
 	WPAS_DBUS_PROP_ROAM_COMPLETE,
 	WPAS_DBUS_PROP_SESSION_LENGTH,
+	WPAS_DBUS_PROP_BSS_TM_STATUS,
 };
 
 enum wpas_dbus_bss_prop {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index e84acf230..c9159228c 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3223,6 +3223,28 @@ dbus_bool_t wpas_dbus_getter_session_length(
 }
 
 
+/**
+ * wpas_dbus_getter_bss_tm_status - Get most BSS Transition Management request
+ * status code
+ * @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 "BSSTMStatus" property.
+ */
+dbus_bool_t wpas_dbus_getter_bss_tm_status(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_uint32_t bss_tm_status = wpa_s->bss_tm_status;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+						&bss_tm_status, error);
+}
+
+
 /**
  * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
  * @iter: Pointer to incoming dbus message iter
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 7a03b7f9f..25ab9991c 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -151,6 +151,7 @@ DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
 DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
 DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
 DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
+DECLARE_ACCESSOR(wpas_dbus_getter_bss_tm_status);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index a2b04716d..b171e8e87 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -176,6 +176,15 @@ void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
 }
 
 
+void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS);
+}
+
+
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->p2p_mgmt)
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index bde20e83d..9605785cf 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -27,6 +27,7 @@ void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s);
 void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
 void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
 void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
+void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
 void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
 void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index 7c410e730..1dbc90352 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -20,6 +20,7 @@
 #include "ctrl_iface.h"
 #include "bss.h"
 #include "wnm_sta.h"
+#include "notify.h"
 #include "hs20_supplicant.h"
 
 #define MAX_TFS_IE_LEN  1024
@@ -938,6 +939,9 @@ static void wnm_send_bss_transition_mgmt_resp(
 		return;
 	}
 
+        wpa_s->bss_tm_status = status;
+        wpas_notify_bss_tm_status(wpa_s);
+
 	wpabuf_put_u8(buf, WLAN_ACTION_WNM);
 	wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_RESP);
 	wpabuf_put_u8(buf, dialog_token);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index a4d56b810..70da2a4b1 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1059,6 +1059,7 @@ struct wpa_supplicant {
 	struct neighbor_report *wnm_neighbor_report_elements;
 	struct os_reltime wnm_cand_valid_until;
 	u8 wnm_cand_from_bss[ETH_ALEN];
+        enum bss_trans_mgmt_status_code bss_tm_status;
 #ifdef CONFIG_MBO
 	unsigned int wnm_mbo_trans_reason_present:1;
 	u8 wnm_mbo_transition_reason;
-- 
2.17.0.441.gb46fe60e1d-goog



From sven.eckelmann at openmesh.com  Mon May  7 06:24:29 2018
From: sven.eckelmann at openmesh.com (Sven Eckelmann)
Date: Mon,  7 May 2018 15:24:29 +0200
Subject: [PATCH] wpa_supplicant: Fix parsing of max_oper_chwidth
Message-ID: <20180507132429.17759-1-sven.eckelmann@openmesh.com>

The max_oper_chwidth is parsed in wpa_config_set as INT_RANGE (see
ssid_fields). The actual parsing for INT_RANGE is done by
wpa_config_parse_int which can only store the result as full integer.

max_oper_chwidth is stored as u8 (a single byte) in wpa_ssid. This means
that on little endian systems, the least significant byte of the parsed
value are really stored in the max_oper_chwidth. But on big endian system,
the only most significant byte is stored as max_oper_chwidth. This means
that 0 is always stored because the provided range doesn't allow any other
value for systems with multi-byte-wide integers.

This also means that for common systems with 4-byte-wide integers, the
remaining 3 bytes were written after the actual member of the struct. This
should not have influenced the behavior of succeeding members because these
bytes would have been part of the padding between the members on most
systems.

Increasing its size to a full int fixes the write operations outside of the
member and allows to use the max_oper_chwidth setting on big endian
systems.

Fixes: 0f29bc68d18e ("IBSS/mesh: Add support for VHT80P80 configuration")
Signed-off-by: Sven Eckelmann <sven.eckelmann at openmesh.com>
---
Cc: Ahmad Kholaif <akholaif at qca.qualcomm.com>
Cc: Jouni Malinen <jouni at qca.qualcomm.com>

 wpa_supplicant/config_ssid.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 9fd56c32f..65007795b 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -497,7 +497,7 @@ struct wpa_ssid {
 
 	int vht;
 
-	u8 max_oper_chwidth;
+	int max_oper_chwidth;
 
 	unsigned int vht_center_freq1;
 	unsigned int vht_center_freq2;
-- 
2.11.0



From andrew.shadura at collabora.co.uk  Mon May  7 11:19:49 2018
From: andrew.shadura at collabora.co.uk (Andrej Shadura)
Date: Mon,  7 May 2018 20:19:49 +0200
Subject: [PATCH] dbus: Expose connected stations on D-Bus
Message-ID: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>

From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>

Make it possible to list connected stations in AP mode over D-Bus, along
with some of their properties: rx/tx packets, bytes, capabilities, etc.

Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>

Rebased by Julian Andres Klode <juliank at ubuntu.com> and updated to use
the new getter API.

Further modified by Andrej Shadura to not error out when not in AP mode.

Signed-off-by: Andrej Shadura <andrew.shadura at collabora.co.uk>
---
 wpa_supplicant/dbus/dbus_new.c          | 245 +++++++++++++++++--
 wpa_supplicant/dbus/dbus_new.h          |  25 ++
 wpa_supplicant/dbus/dbus_new_handlers.c | 313 ++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  14 ++
 wpa_supplicant/notify.c                 |   6 +
 5 files changed, 589 insertions(+), 14 deletions(-)

diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index e0f16bbda..4139131e9 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -25,6 +25,7 @@
 #include "dbus_new_handlers_p2p.h"
 #include "p2p/p2p.h"
 #include "../p2p_supplicant.h"
+#include "ap/sta_info.h"
 
 #ifdef CONFIG_AP /* until needed by something else */
 
@@ -1016,15 +1017,19 @@ void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
  * Notify listeners about event related with station
  */
 static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
-				 const u8 *sta, const char *sig_name)
+				 const u8 *sta, const char *sig_name,
+                                 int properties)
 {
 	struct wpas_dbus_priv *iface;
 	DBusMessage *msg;
-	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
-	char *dev_mac;
+	DBusMessageIter iter;
+	char sta_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
+	char *path;
 
-	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
-	dev_mac = sta_mac;
+	os_snprintf(sta_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
+		    wpa_s->dbus_new_path, MAC2STR(sta));
+	path = sta_obj_path;
 
 	iface = wpa_s->global->dbus;
 
@@ -1037,15 +1042,28 @@ static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
 	if (msg == NULL)
 		return;
 
-	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
-				     DBUS_TYPE_INVALID))
-		dbus_connection_send(iface->con, msg, NULL);
-	else
-		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	dbus_message_iter_init_append(msg, &iter);
+	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+					    &path))
+		goto err;
+
+	if (properties) {
+		if (!wpa_dbus_get_object_properties(iface, path,
+						    WPAS_DBUS_NEW_IFACE_STA,
+						    &iter))
+			goto err;
+	}
+
+	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '" MACSTR "' '%s'",
+		   MAC2STR(sta), sig_name);
+
+	dbus_connection_send(iface->con, msg, NULL);
 	dbus_message_unref(msg);
+	return;
 
-	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
-		   sta_mac, sig_name);
+err:
+	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	dbus_message_unref(msg);
 }
 
 
@@ -1059,7 +1077,7 @@ static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
 void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
 				     const u8 *sta)
 {
-	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
+	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized", TRUE);
 }
 
 
@@ -1073,7 +1091,7 @@ void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
 void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
 				       const u8 *sta)
 {
-	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
+	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized", FALSE);
 }
 
 
@@ -2151,6 +2169,9 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
 	case WPAS_DBUS_PROP_BSSS:
 		prop = "BSSs";
 		break;
+	case WPAS_DBUS_PROP_STAS:
+		prop = "Stations";
+		break;
 	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
 		prop = "CurrentAuthMode";
 		break;
@@ -2243,6 +2264,39 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
 }
 
 
+/**
+ * wpas_dbus_sta_signal_prop_changed - Signals change of STA property
+ * @wpa_s: %wpa_supplicant network interface data
+ * @property: indicates which property has changed
+ * @address: unique BSS identifier
+ *
+ * Sends PropertyChanged signals with path, interface, and arguments depending
+ * on which property has changed.
+ */
+void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s,
+				       enum wpas_dbus_bss_prop property,
+				       u8 address[ETH_ALEN])
+{
+	char path[WPAS_DBUS_OBJECT_PATH_MAX];
+	char *prop;
+
+	switch (property) {
+	case WPAS_DBUS_STA_PROP_ADDRESS:
+		prop = "Address";
+		break;
+	default:
+		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
+			   __func__, property);
+		return;
+	}
+
+	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
+		    wpa_s->dbus_new_path, MAC2STR(address));
+
+	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
+				       WPAS_DBUS_NEW_IFACE_STA, prop);
+}
 /**
  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
  * @global: wpa_global structure
@@ -2857,6 +2911,164 @@ err:
 }
 
 
+static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = {
+	{ "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
+	  wpas_dbus_getter_sta_address,
+	  NULL
+	},
+	{ "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
+	  wpas_dbus_getter_sta_aid,
+	  NULL
+	},
+	{ "Flags", WPAS_DBUS_NEW_IFACE_STA, "u",
+	  wpas_dbus_getter_sta_flags,
+	  NULL
+	},
+	{ "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
+	  wpas_dbus_getter_sta_caps,
+	  NULL
+	},
+	{ "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
+	  wpas_dbus_getter_sta_rx_packets,
+	  NULL
+	},
+	{ "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
+	  wpas_dbus_getter_sta_tx_packets,
+	  NULL
+	},
+	{ "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
+	  wpas_dbus_getter_sta_rx_bytes,
+	  NULL
+	},
+	{ "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
+	  wpas_dbus_getter_sta_tx_bytes,
+	  NULL
+	},
+	{ NULL, NULL, NULL, NULL, NULL }
+};
+
+
+static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
+	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
+	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
+	  {
+		  { "properties", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ NULL, NULL, { END_ARGS } }
+};
+
+
+/**
+ * wpas_dbus_unregister_sta - Unregister a connected station from dbus
+ * @wpa_s: wpa_supplicant interface structure
+ * @bssid: connected station bssid
+ * @id: unique station identifier
+ * Returns: 0 on success, -1 on failure
+ *
+ * Unregisters STA representing object from dbus
+ */
+int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s,
+			     const u8 *sta)
+{
+	struct wpas_dbus_priv *ctrl_iface;
+	char sta_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
+
+	/* Do nothing if the control interface is not turned on */
+	if (wpa_s == NULL || wpa_s->global == NULL)
+		return 0;
+	ctrl_iface = wpa_s->global->dbus;
+	if (ctrl_iface == NULL)
+		return 0;
+
+	os_snprintf(sta_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
+		    wpa_s->dbus_new_path, MAC2STR(sta));
+
+	wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
+		   sta_obj_path);
+	if (wpa_dbus_unregister_object_per_iface(ctrl_iface, sta_obj_path)) {
+		wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s",
+			   sta_obj_path);
+		return -1;
+	}
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STAS);
+
+	return 0;
+}
+
+
+/**
+ * wpas_dbus_register_sta - Register a scanned station with dbus
+ * @wpa_s: wpa_supplicant interface structure
+ * @bssid: connection network station
+ * @id: unique STA identifier
+ * Returns: 0 on success, -1 on failure
+ *
+ * Registers STA representing object with dbus
+ */
+int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s,
+			   const u8 *sta)
+{
+	struct wpas_dbus_priv *ctrl_iface;
+	struct wpa_dbus_object_desc *obj_desc;
+	char sta_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
+	struct sta_handler_args *arg;
+
+	/* Do nothing if the control interface is not turned on */
+	if (wpa_s == NULL || wpa_s->global == NULL)
+		return 0;
+	ctrl_iface = wpa_s->global->dbus;
+	if (ctrl_iface == NULL)
+		return 0;
+
+	os_snprintf(sta_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
+		    wpa_s->dbus_new_path, MAC2STR(sta));
+
+	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
+	if (!obj_desc) {
+		wpa_printf(MSG_ERROR, "Not enough memory "
+			   "to create object description");
+		goto err;
+	}
+
+	arg = os_zalloc(sizeof(struct sta_handler_args));
+	if (!arg) {
+		wpa_printf(MSG_ERROR, "Not enough memory "
+			   "to create arguments for handler");
+		goto err;
+	}
+	arg->wpa_s = wpa_s;
+	arg->sta = sta;
+
+	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
+			   NULL,
+			   wpas_dbus_sta_properties,
+			   wpas_dbus_sta_signals);
+
+	wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
+		   sta_obj_path);
+	if (wpa_dbus_register_object_per_iface(ctrl_iface, sta_obj_path,
+					       wpa_s->ifname, obj_desc)) {
+		wpa_printf(MSG_ERROR,
+			   "Cannot register STA dbus object %s.",
+			   sta_obj_path);
+		goto err;
+	}
+
+	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STAS);
+
+	return 0;
+
+err:
+	free_dbus_object_desc(obj_desc);
+	return -1;
+}
+
+
 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  (WPADBusMethodHandler) wpas_dbus_handler_scan,
@@ -3501,6 +3713,11 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
 	  NULL
 	},
 #endif /* CONFIG_MESH */
+	{ "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
+	  wpas_dbus_getter_stas,
+	  NULL,
+	  NULL
+	},
 	{ NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index e68acb7a1..f434cc147 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -12,6 +12,7 @@
 
 #include "common/defs.h"
 #include "p2p/p2p.h"
+#include "ap/sta_info.h"
 
 struct wpa_global;
 struct wpa_supplicant;
@@ -29,6 +30,7 @@ enum wpas_dbus_prop {
 	WPAS_DBUS_PROP_CURRENT_NETWORK,
 	WPAS_DBUS_PROP_CURRENT_AUTH_MODE,
 	WPAS_DBUS_PROP_BSSS,
+	WPAS_DBUS_PROP_STAS,
 	WPAS_DBUS_PROP_DISCONNECT_REASON,
 	WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
 };
@@ -46,6 +48,10 @@ enum wpas_dbus_bss_prop {
 	WPAS_DBUS_BSS_PROP_AGE,
 };
 
+enum wpas_dbus_sta_prop {
+	WPAS_DBUS_STA_PROP_ADDRESS,
+};
+
 #define WPAS_DBUS_OBJECT_PATH_MAX 150
 
 #define WPAS_DBUS_NEW_SERVICE		"fi.w1.wpa_supplicant1"
@@ -62,6 +68,9 @@ enum wpas_dbus_bss_prop {
 #define WPAS_DBUS_NEW_BSSIDS_PART "BSSs"
 #define WPAS_DBUS_NEW_IFACE_BSS	WPAS_DBUS_NEW_INTERFACE ".BSS"
 
+#define WPAS_DBUS_NEW_STAS_PART "Stations"
+#define WPAS_DBUS_NEW_IFACE_STA	WPAS_DBUS_NEW_INTERFACE ".Station"
+
 #define WPAS_DBUS_NEW_IFACE_P2PDEVICE	\
 		WPAS_DBUS_NEW_IFACE_INTERFACE ".P2PDevice"
 
@@ -164,6 +173,10 @@ int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
 			     u8 bssid[ETH_ALEN], unsigned int id);
 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
 			   u8 bssid[ETH_ALEN], unsigned int id);
+int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s,
+			     const u8 *sta);
+int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s,
+			   const u8 *sta);
 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
 				 const char *name);
 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
@@ -346,6 +359,18 @@ static inline int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
 	return 0;
 }
 
+static inline int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s,
+					   const u8 *sta)
+{
+	return 0;
+}
+
+static inline int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s,
+					 const u8 *sta)
+{
+	return 0;
+}
+
 static inline void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
 					       const char *name)
 {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index a3c98fadd..01a5bdb86 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -22,6 +22,10 @@
 #include "../bss.h"
 #include "../scan.h"
 #include "../autoscan.h"
+#include "../ap.h"
+#include "ap/hostapd.h"
+#include "ap/sta_info.h"
+#include "ap/ap_drv_ops.h"
 #include "dbus_new_helpers.h"
 #include "dbus_new.h"
 #include "dbus_new_handlers.h"
@@ -3854,6 +3858,315 @@ dbus_bool_t wpas_dbus_setter_iface_global(
 }
 
 
+/**
+ * wpas_dbus_getter_stas - Get connected stations for an interface
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: a list of stations
+ *
+ * Getter for "Stations" property.
+ */
+dbus_bool_t wpas_dbus_getter_stas(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	struct hostapd_data *hapd;
+	struct sta_info *sta = NULL;
+	char **paths = NULL;
+	unsigned int i = 0, num = 0;
+	dbus_bool_t success = FALSE;
+
+	if (!wpa_s->dbus_new_path) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: no D-Bus interface", __func__);
+		return FALSE;
+	}
+
+	if (wpa_s->ap_iface) {
+		hapd = wpa_s->ap_iface->bss[0];
+		sta = hapd->sta_list;
+		num = hapd->num_sta;
+	}
+
+	paths = os_calloc(num, sizeof(char *));
+	if (!paths) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	/* Loop through scan results and append each result's object path */
+	for (; sta; sta = sta->next) {
+		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
+		if (paths[i] == NULL) {
+			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+					     "no memory");
+			goto out;
+		}
+		/* Construct the object path for this BSS. */
+		os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
+			    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
+			    wpa_s->dbus_new_path, MAC2STR(sta->addr));
+	}
+
+	success = wpas_dbus_simple_array_property_getter(iter,
+							 DBUS_TYPE_OBJECT_PATH,
+							 paths, num,
+							 error);
+
+out:
+	while (i)
+		os_free(paths[--i]);
+	os_free(paths);
+	return success;
+}
+
+
+/**
+ * wpas_dbus_getter_sta_address - Return the BSSID of a connected station
+ * @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 "Address" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_address(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+
+	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
+	if (!sta)
+		return FALSE;
+
+	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						      sta->addr, ETH_ALEN,
+						      error);
+}
+
+
+/**
+ * wpas_dbus_getter_sta_aid - Return the AID of a connected station
+ * @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 "AID" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_aid(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+
+	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
+	if (!sta)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
+						&sta->aid,
+						error);
+}
+
+
+/**
+ * wpas_dbus_getter_sta_flags - Return the flags of a connected station
+ * @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 "Flags" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_flags(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+
+	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
+	if (!sta)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+						&sta->flags,
+						error);
+}
+
+
+/**
+ * wpas_dbus_getter_sta_caps - Return the capabilities of a station
+ * @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 "Capabilities" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_caps(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+
+	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
+	if (!sta)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
+						&sta->capability,
+						error);
+}
+
+
+/**
+ * wpas_dbus_getter_rx_packets - Return the received packets for a station
+ * @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 "RxPackets" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_rx_packets(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+	struct hostap_sta_driver_data data;
+	struct hostapd_data *hapd;
+
+	if (!args->wpa_s->ap_iface)
+		return FALSE;
+
+	hapd = args->wpa_s->ap_iface->bss[0];
+	sta = ap_get_sta(hapd, args->sta);
+	if (!sta)
+		return FALSE;
+
+        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
+						&data.rx_packets,
+						error);
+}
+
+
+/**
+ * wpas_dbus_getter_tx_packets - Return the transmitted packets for a station
+ * @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 "TxPackets" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_tx_packets(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+	struct hostap_sta_driver_data data;
+	struct hostapd_data *hapd;
+
+	if (!args->wpa_s->ap_iface)
+		return FALSE;
+
+	hapd = args->wpa_s->ap_iface->bss[0];
+	sta = ap_get_sta(hapd, args->sta);
+	if (!sta)
+		return FALSE;
+
+        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
+						&data.tx_packets,
+						error);
+}
+
+
+/**
+ * wpas_dbus_getter_tx_bytes - Return the transmitted bytes for a station
+ * @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 "TxBytes" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_tx_bytes(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+	struct hostap_sta_driver_data data;
+	struct hostapd_data *hapd;
+
+	if (!args->wpa_s->ap_iface)
+		return FALSE;
+
+	hapd = args->wpa_s->ap_iface->bss[0];
+	sta = ap_get_sta(hapd, args->sta);
+	if (!sta)
+		return FALSE;
+
+        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
+						&data.tx_bytes,
+						error);
+}
+
+
+/**
+ * wpas_dbus_getter_rx_bytes - Return the received bytes for a station
+ * @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 "RxBytes" property.
+ */
+dbus_bool_t wpas_dbus_getter_sta_rx_bytes(
+	const struct wpa_dbus_property_desc *property_desc,
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct sta_handler_args *args = user_data;
+	struct sta_info *sta;
+	struct hostap_sta_driver_data data;
+	struct hostapd_data *hapd;
+
+	if (!args->wpa_s->ap_iface)
+		return FALSE;
+
+	hapd = args->wpa_s->ap_iface->bss[0];
+	sta = ap_get_sta(hapd, args->sta);
+	if (!sta)
+		return FALSE;
+
+        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
+		return FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
+						&data.rx_bytes,
+						error);
+}
+
+
 static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
 				       DBusError *error, const char *func_name)
 {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 26652ad3d..9a4f66171 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -22,6 +22,11 @@ struct bss_handler_args {
 	unsigned int id;
 };
 
+struct sta_handler_args {
+	struct wpa_supplicant *wpa_s;
+	const u8 *sta;
+};
+
 dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
 					     const int type,
 					     const void *val,
@@ -168,6 +173,15 @@ DECLARE_ACCESSOR(wpas_dbus_getter_networks);
 DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_engine_path);
 DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path);
 DECLARE_ACCESSOR(wpas_dbus_getter_blobs);
+DECLARE_ACCESSOR(wpas_dbus_getter_stas);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_address);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_flags);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_packets);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_packets);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_bytes);
+DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_bytes);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_bssid);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_ssid);
 DECLARE_ACCESSOR(wpas_dbus_getter_bss_privacy);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 83df04f39..b9bbe260a 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -720,6 +720,9 @@ static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
 		wpas_dbus_signal_p2p_peer_joined(wpa_s, p2p_dev_addr);
 #endif /* CONFIG_P2P */
 
+	/* Unregister the station */
+	wpas_dbus_register_sta(wpa_s, sta);
+
 	/* Notify listeners a new station has been authorized */
 	wpas_dbus_signal_sta_authorized(wpa_s, sta);
 }
@@ -740,6 +743,9 @@ static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
 
 	/* Notify listeners a station has been deauthorized */
 	wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
+
+	/* Unregister the station */
+	wpas_dbus_unregister_sta(wpa_s, sta);
 }
 
 
-- 
2.17.0



From sean at wolfssl.com  Mon May  7 16:26:45 2018
From: sean at wolfssl.com (Sean Parkinson)
Date: Tue, 8 May 2018 09:26:45 +1000
Subject: Proposed Patch: Support for wolfSSL
In-Reply-To: <20180502150035.GA31057@w1.fi>
References: <35F71B52-8428-4A0E-B14C-20CFF8CBCA65@wolfssl.com>
 <20180303191907.GA13466@w1.fi>
 <CE258BE9-FCBE-47C0-B7AB-C95AA65320ED@wolfssl.com>
 <20180502150035.GA31057@w1.fi>
Message-ID: <7EA3DD5D-CD3E-4F4C-A98F-F2766FCFAB7C@wolfssl.com>

Hi Jouni,

I?ve been able to fix the ECDH problem and the error tests.
The EAP tests listed are not failing for me.
I?m using Ubuntu 14.04.1 in a virtual machine, with the OpenSSL that comes with it, as recommended in example-setup.txt.
What setup are you testing on?

See below for the patch file.

Sean
?
Sean Parkinson
sean at wolfssl.com
wolfSSL Inc



From 50827b00c8c8330ec03b09e6b51a9e06ac182162 Mon Sep 17 00:00:00 2001
From: Sean Parkinson <sparki at wolfssl.com>
Date: Tue, 8 May 2018 09:20:44 +1000
Subject: [PATCH] Fixes for wolfSSL

Fix for ECDH set peer to use the index when importing point.
Modified DH initialization to call TEST_FAIL() for error tests.

Signed-off-by: Sean Parkinson <sean at wolfssl.com>
---
 src/crypto/crypto_wolfssl.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index fc9a67b..bc4fd6a 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -783,6 +783,9 @@ int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
 	DhKey *dh = NULL;
 	word32 priv_sz, pub_sz;
 
+	if (TEST_FAIL())
+		return -1;
+
 	dh = os_malloc(sizeof(DhKey));
 	if (!dh)
 		return -1;
@@ -1762,7 +1765,7 @@ struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
 		goto fail;
 
 	ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
-				      ecdh->ec->key.dp->id, point);
+				      ecdh->ec->key.idx, point);
 	if (ret != MP_OKAY)
 		goto fail;
 
-- 
1.9.1



> On 3 May 2018, at 1:00 am, Jouni Malinen <j at w1.fi> wrote:
> 
> On Thu, Mar 29, 2018 at 02:55:55PM +1000, Sean Parkinson wrote:
>> I?ve looked into the failures and made changes as needed.
>> There were changes to wolfSSL as well.
>> 
>> To reproduce the setup I tested:
>> - download wolfSSL latest from master (https://github.com/wolfssl/wolfssl)
>> - configure wolfSSL with option -enable-wpas
>> - build wolfSSL
>> - in wpa_supplicant change .config
>>   - CONFIG_TLS=wolfssl
>>   - disable CONFIG_DPP
>> 
>> The proposed new patch is below.
> 
> Thanks. I applied this as number of smaller commits to make it easier to
> review and understand. I did some cleanup and couple of fixes while
> going through the changes as well.
> 
> There are some remaining issues, but it looks like this is a reasonable
> step forward, so I included or the changes even though it looks like
> there is something wrong with the ECDH wrappers (at least
> crypto_ecdh_set_peerkey() fails to work properly).
> 
> The crypto_ecdh_set_peerkey() version in the patch you sent was broken,
> i.e., it actually ended up causing process termination due to invalid
> wpabuf_put() use that hit the buffer bounds checking routine. I fixed
> that to use wpabuf_mhead() instead of wpabuf_put() since the
> wc_ecc_import_point_der() call was clearly trying to use the already
> generated buffer instead of trying to add something more into the
> buffer. While this removed the process termination part, something is
> still failing.. That wc_ecc_import_point_der() call fails every now and
> then and even if it succeeds, the ECDH shared secret from
> wc_ecc_shared_secret_ex() does not match the one that the AP derives
> (i.e., using crypto_openssl.c on the other end of the connection).
> 
> As far as wolfSSL changes for --enable-wpas case are concerned, please
> note that I had to revert the GetName() change in wolfcrypt/src/asn.c
> (i.e., do not add an extra '=' to make the one-line name output look
> like /CN==FI/ instead of /CN=FI/). This was added in wolfssl commit
> b325e0ff916aa5989c523e7619f4dbbbeded74a1 ("Fixes for wpa_supplicant")
> for some reason, but it results in a failure in one of the hwsim test
> cases that verifies the exact contents of the server certificate name.
> 
> As far as remaining failures from wpa_supplicant build using current
> wolfSSL snapshot against hostapd build using OpenSSL are concerned, I'm
> seeing following issues:
> - quite a few EAP-FAST test cases are failing
> - ap_wpa2_eap_tls_versions is failing since tls_wolfssl.c returns
>  "unknown" from tls_get_version() (i.e., wolfSSL_get_version())
> - all OWE test cases are failing (that ECDH issue)
> - all FILS PFS test cases are failing (ECDH)
> - some EAP protocol test case failures
> 
> I haven't looked at these in much detail yet, but this is the list of
> failing test cases from my tests:
> 
> ap_wpa2_eap_fast_binary_pac
> ap_wpa2_eap_fast_binary_pac_errors
> ap_wpa2_eap_fast_mschapv2_unauth_prov
> ap_wpa2_eap_fast_pac_file
> ap_wpa2_eap_fast_pac_refresh
> ap_wpa2_eap_fast_pac_truncate
> ap_wpa2_eap_fast_prov
> ap_wpa2_eap_fast_server_oom
> ap_wpa2_eap_fast_text_pac_errors
> ap_wpa2_eap_ikev2_oom
> ap_wpa2_eap_pwd_groups
> ap_wpa2_eap_tls_versions
> eap_mschapv2_errors
> eap_proto_eke_errors
> eap_proto_fast_errors
> fils_sk_pfs_20
> fils_sk_pfs_21
> fils_sk_pfs_26
> owe
> owe_and_psk
> owe_group_negotiation
> owe_group_negotiation_connect_cmd
> owe_groups
> owe_limited_group_set
> owe_pmksa_caching
> owe_pmksa_caching_connect_cmd
> owe_transition_mode
> owe_transition_mode_connect_cmd
> owe_transition_mode_multi_bss
> sigma_dut_ap_owe
> sigma_dut_ap_owe_ecgroupid
> sigma_dut_ap_owe_transition_mode
> sigma_dut_ap_owe_transition_mode_2
> sigma_dut_owe
> 
> -- 
> Jouni Malinen                                            PGP id EFC895FA



From dcbw at redhat.com  Tue May  8 09:53:58 2018
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 08 May 2018 11:53:58 -0500
Subject: [PATCH] dbus: Expose connected stations on D-Bus
In-Reply-To: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>
References: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>
Message-ID: <44963247e199bb798406d34c1d0ebe397c421a0e.camel@redhat.com>

On Mon, 2018-05-07 at 20:19 +0200, Andrej Shadura wrote:
> From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>
> 
> Make it possible to list connected stations in AP mode over D-Bus,
> along
> with some of their properties: rx/tx packets, bytes, capabilities,
> etc.

It looks like this patch changes the signal signature of
StaAuthorized/StaDeauthorized, is that correct?  That won't be
backwards compatible with existing D-Bus clients and we should probably
choose new signal names to allow old clients to continue working.

Also, you'll want to update doc/dbus.doxygen with any changes you make
to the D-Bus API, including additions.

Dan

> Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-
> lapierre at canonical.com>
> 
> Rebased by Julian Andres Klode <juliank at ubuntu.com> and updated to
> use
> the new getter API.
> 
> Further modified by Andrej Shadura to not error out when not in AP
> mode.
> 
> Signed-off-by: Andrej Shadura <andrew.shadura at collabora.co.uk>
> ---
>  wpa_supplicant/dbus/dbus_new.c          | 245 +++++++++++++++++--
>  wpa_supplicant/dbus/dbus_new.h          |  25 ++
>  wpa_supplicant/dbus/dbus_new_handlers.c | 313
> ++++++++++++++++++++++++
>  wpa_supplicant/dbus/dbus_new_handlers.h |  14 ++
>  wpa_supplicant/notify.c                 |   6 +
>  5 files changed, 589 insertions(+), 14 deletions(-)
> 
> diff --git a/wpa_supplicant/dbus/dbus_new.c
> b/wpa_supplicant/dbus/dbus_new.c
> index e0f16bbda..4139131e9 100644
> --- a/wpa_supplicant/dbus/dbus_new.c
> +++ b/wpa_supplicant/dbus/dbus_new.c
> @@ -25,6 +25,7 @@
>  #include "dbus_new_handlers_p2p.h"
>  #include "p2p/p2p.h"
>  #include "../p2p_supplicant.h"
> +#include "ap/sta_info.h"
>  
>  #ifdef CONFIG_AP /* until needed by something else */
>  
> @@ -1016,15 +1017,19 @@ void wpas_dbus_signal_eap_status(struct
> wpa_supplicant *wpa_s,
>   * Notify listeners about event related with station
>   */
>  static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
> -				 const u8 *sta, const char
> *sig_name)
> +				 const u8 *sta, const char
> *sig_name,
> +                                 int properties)

This is just a bool, so maybe dbus_bool_t would be more appropriate.

>  {
>  	struct wpas_dbus_priv *iface;
>  	DBusMessage *msg;
> -	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
> -	char *dev_mac;
> +	DBusMessageIter iter;
> +	char sta_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
> +	char *path;
>  
> -	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR,
> MAC2STR(sta));
> -	dev_mac = sta_mac;
> +	os_snprintf(sta_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
> +		    "%s/" WPAS_DBUS_NEW_STAS_PART "/"
> COMPACT_MACSTR,
> +		    wpa_s->dbus_new_path, MAC2STR(sta));
> +	path = sta_obj_path;
>  
>  	iface = wpa_s->global->dbus;
>  
> @@ -1037,15 +1042,28 @@ static void wpas_dbus_signal_sta(struct
> wpa_supplicant *wpa_s,
>  	if (msg == NULL)
>  		return;
>  
> -	if (dbus_message_append_args(msg, DBUS_TYPE_STRING,
> &dev_mac,
> -				     DBUS_TYPE_INVALID))
> -		dbus_connection_send(iface->con, msg, NULL);
> -	else
> -		wpa_printf(MSG_ERROR, "dbus: Failed to construct
> signal");
> +	dbus_message_iter_init_append(msg, &iter);
> +	if (!dbus_message_iter_append_basic(&iter,
> DBUS_TYPE_OBJECT_PATH,
> +					    &path))
> +		goto err;
> +
> +	if (properties) {
> +		if (!wpa_dbus_get_object_properties(iface, path,
> +						    WPAS_DBUS_NEW_IF
> ACE_STA,
> +						    &iter))
> +			goto err;
> +	}
> +
> +	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '" MACSTR
> "' '%s'",
> +		   MAC2STR(sta), sig_name);
> +
> +	dbus_connection_send(iface->con, msg, NULL);
>  	dbus_message_unref(msg);
> +	return;
>  
> -	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
> -		   sta_mac, sig_name);
> +err:
> +	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
> +	dbus_message_unref(msg);
>  }
>  
>  
> @@ -1059,7 +1077,7 @@ static void wpas_dbus_signal_sta(struct
> wpa_supplicant *wpa_s,
>  void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
>  				     const u8 *sta)
>  {
> -	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
> +	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized", TRUE);
>  }
>  
>  
> @@ -1073,7 +1091,7 @@ void wpas_dbus_signal_sta_authorized(struct
> wpa_supplicant *wpa_s,
>  void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
>  				       const u8 *sta)
>  {
> -	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
> +	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized", FALSE);
>  }
>  
>  
> @@ -2151,6 +2169,9 @@ void wpas_dbus_signal_prop_changed(struct
> wpa_supplicant *wpa_s,
>  	case WPAS_DBUS_PROP_BSSS:
>  		prop = "BSSs";
>  		break;
> +	case WPAS_DBUS_PROP_STAS:
> +		prop = "Stations";
> +		break;
>  	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
>  		prop = "CurrentAuthMode";
>  		break;
> @@ -2243,6 +2264,39 @@ void wpas_dbus_bss_signal_prop_changed(struct
> wpa_supplicant *wpa_s,
>  }
>  
>  
> +/**
> + * wpas_dbus_sta_signal_prop_changed - Signals change of STA
> property
> + * @wpa_s: %wpa_supplicant network interface data
> + * @property: indicates which property has changed
> + * @address: unique BSS identifier
> + *
> + * Sends PropertyChanged signals with path, interface, and arguments
> depending
> + * on which property has changed.
> + */
> +void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s,
> +				       enum wpas_dbus_bss_prop
> property,
> +				       u8 address[ETH_ALEN])
> +{
> +	char path[WPAS_DBUS_OBJECT_PATH_MAX];
> +	char *prop;
> +
> +	switch (property) {
> +	case WPAS_DBUS_STA_PROP_ADDRESS:
> +		prop = "Address";
> +		break;
> +	default:
> +		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property
> value %d",
> +			   __func__, property);
> +		return;
> +	}
> +
> +	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
> +		    "%s/" WPAS_DBUS_NEW_STAS_PART "/"
> COMPACT_MACSTR,
> +		    wpa_s->dbus_new_path, MAC2STR(address));
> +
> +	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
> +				       WPAS_DBUS_NEW_IFACE_STA,
> prop);
> +}
>  /**
>   * wpas_dbus_signal_debug_level_changed - Signals change of debug
> param
>   * @global: wpa_global structure
> @@ -2857,6 +2911,164 @@ err:
>  }
>  
>  
> +static const struct wpa_dbus_property_desc
> wpas_dbus_sta_properties[] = {
> +	{ "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
> +	  wpas_dbus_getter_sta_address,
> +	  NULL
> +	},
> +	{ "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
> +	  wpas_dbus_getter_sta_aid,
> +	  NULL
> +	},
> +	{ "Flags", WPAS_DBUS_NEW_IFACE_STA, "u",
> +	  wpas_dbus_getter_sta_flags,
> +	  NULL
> +	},
> +	{ "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
> +	  wpas_dbus_getter_sta_caps,
> +	  NULL
> +	},
> +	{ "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
> +	  wpas_dbus_getter_sta_rx_packets,
> +	  NULL
> +	},
> +	{ "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
> +	  wpas_dbus_getter_sta_tx_packets,
> +	  NULL
> +	},
> +	{ "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
> +	  wpas_dbus_getter_sta_rx_bytes,
> +	  NULL
> +	},
> +	{ "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
> +	  wpas_dbus_getter_sta_tx_bytes,
> +	  NULL
> +	},
> +	{ NULL, NULL, NULL, NULL, NULL }
> +};
> +
> +
> +static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
> +	/* Deprecated: use
> org.freedesktop.DBus.Properties.PropertiesChanged */
> +	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
> +	  {
> +		  { "properties", "a{sv}", ARG_OUT },
> +		  END_ARGS
> +	  }
> +	},
> +	{ NULL, NULL, { END_ARGS } }
> +};
> +
> +
> +/**
> + * wpas_dbus_unregister_sta - Unregister a connected station from
> dbus
> + * @wpa_s: wpa_supplicant interface structure
> + * @bssid: connected station bssid
> + * @id: unique station identifier
> + * Returns: 0 on success, -1 on failure
> + *
> + * Unregisters STA representing object from dbus
> + */
> +int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s,
> +			     const u8 *sta)
> +{
> +	struct wpas_dbus_priv *ctrl_iface;
> +	char sta_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
> +
> +	/* Do nothing if the control interface is not turned on */
> +	if (wpa_s == NULL || wpa_s->global == NULL)
> +		return 0;
> +	ctrl_iface = wpa_s->global->dbus;
> +	if (ctrl_iface == NULL)
> +		return 0;
> +
> +	os_snprintf(sta_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
> +		    "%s/" WPAS_DBUS_NEW_STAS_PART "/"
> COMPACT_MACSTR,
> +		    wpa_s->dbus_new_path, MAC2STR(sta));
> +
> +	wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
> +		   sta_obj_path);
> +	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
> sta_obj_path)) {
> +		wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA
> object %s",
> +			   sta_obj_path);
> +		return -1;
> +	}
> +
> +	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STAS);
> +
> +	return 0;
> +}
> +
> +
> +/**
> + * wpas_dbus_register_sta - Register a scanned station with dbus
> + * @wpa_s: wpa_supplicant interface structure
> + * @bssid: connection network station
> + * @id: unique STA identifier
> + * Returns: 0 on success, -1 on failure
> + *
> + * Registers STA representing object with dbus
> + */
> +int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s,
> +			   const u8 *sta)
> +{
> +	struct wpas_dbus_priv *ctrl_iface;
> +	struct wpa_dbus_object_desc *obj_desc;
> +	char sta_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
> +	struct sta_handler_args *arg;
> +
> +	/* Do nothing if the control interface is not turned on */
> +	if (wpa_s == NULL || wpa_s->global == NULL)
> +		return 0;
> +	ctrl_iface = wpa_s->global->dbus;
> +	if (ctrl_iface == NULL)
> +		return 0;
> +
> +	os_snprintf(sta_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
> +		    "%s/" WPAS_DBUS_NEW_STAS_PART "/"
> COMPACT_MACSTR,
> +		    wpa_s->dbus_new_path, MAC2STR(sta));
> +
> +	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
> +	if (!obj_desc) {
> +		wpa_printf(MSG_ERROR, "Not enough memory "
> +			   "to create object description");
> +		goto err;
> +	}
> +
> +	arg = os_zalloc(sizeof(struct sta_handler_args));
> +	if (!arg) {
> +		wpa_printf(MSG_ERROR, "Not enough memory "
> +			   "to create arguments for handler");
> +		goto err;
> +	}
> +	arg->wpa_s = wpa_s;
> +	arg->sta = sta;
> +
> +	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
> +			   NULL,
> +			   wpas_dbus_sta_properties,
> +			   wpas_dbus_sta_signals);
> +
> +	wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
> +		   sta_obj_path);
> +	if (wpa_dbus_register_object_per_iface(ctrl_iface,
> sta_obj_path,
> +					       wpa_s->ifname,
> obj_desc)) {
> +		wpa_printf(MSG_ERROR,
> +			   "Cannot register STA dbus object %s.",
> +			   sta_obj_path);
> +		goto err;
> +	}
> +
> +	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STAS);
> +
> +	return 0;
> +
> +err:
> +	free_dbus_object_desc(obj_desc);
> +	return -1;
> +}
> +
> +
>  static const struct wpa_dbus_method_desc
> wpas_dbus_interface_methods[] = {
>  	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
>  	  (WPADBusMethodHandler) wpas_dbus_handler_scan,
> @@ -3501,6 +3713,11 @@ static const struct wpa_dbus_property_desc
> wpas_dbus_interface_properties[] = {
>  	  NULL
>  	},
>  #endif /* CONFIG_MESH */
> +	{ "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
> +	  wpas_dbus_getter_stas,
> +	  NULL,
> +	  NULL
> +	},
>  	{ NULL, NULL, NULL, NULL, NULL, NULL }
>  };
>  
> diff --git a/wpa_supplicant/dbus/dbus_new.h
> b/wpa_supplicant/dbus/dbus_new.h
> index e68acb7a1..f434cc147 100644
> --- a/wpa_supplicant/dbus/dbus_new.h
> +++ b/wpa_supplicant/dbus/dbus_new.h
> @@ -12,6 +12,7 @@
>  
>  #include "common/defs.h"
>  #include "p2p/p2p.h"
> +#include "ap/sta_info.h"
>  
>  struct wpa_global;
>  struct wpa_supplicant;
> @@ -29,6 +30,7 @@ enum wpas_dbus_prop {
>  	WPAS_DBUS_PROP_CURRENT_NETWORK,
>  	WPAS_DBUS_PROP_CURRENT_AUTH_MODE,
>  	WPAS_DBUS_PROP_BSSS,
> +	WPAS_DBUS_PROP_STAS,
>  	WPAS_DBUS_PROP_DISCONNECT_REASON,
>  	WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
>  };
> @@ -46,6 +48,10 @@ enum wpas_dbus_bss_prop {
>  	WPAS_DBUS_BSS_PROP_AGE,
>  };
>  
> +enum wpas_dbus_sta_prop {
> +	WPAS_DBUS_STA_PROP_ADDRESS,
> +};
> +
>  #define WPAS_DBUS_OBJECT_PATH_MAX 150
>  
>  #define WPAS_DBUS_NEW_SERVICE		"fi.w1.wpa_supplicant1"
> @@ -62,6 +68,9 @@ enum wpas_dbus_bss_prop {
>  #define WPAS_DBUS_NEW_BSSIDS_PART "BSSs"
>  #define WPAS_DBUS_NEW_IFACE_BSS	WPAS_DBUS_NEW_INTERFACE
> ".BSS"
>  
> +#define WPAS_DBUS_NEW_STAS_PART "Stations"
> +#define WPAS_DBUS_NEW_IFACE_STA	WPAS_DBUS_NEW_INTERFACE
> ".Station"
> +
>  #define WPAS_DBUS_NEW_IFACE_P2PDEVICE	\
>  		WPAS_DBUS_NEW_IFACE_INTERFACE ".P2PDevice"
>  
> @@ -164,6 +173,10 @@ int wpas_dbus_unregister_bss(struct
> wpa_supplicant *wpa_s,
>  			     u8 bssid[ETH_ALEN], unsigned int id);
>  int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
>  			   u8 bssid[ETH_ALEN], unsigned int id);
> +int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s,
> +			     const u8 *sta);
> +int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s,
> +			   const u8 *sta);
>  void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
>  				 const char *name);
>  void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
> @@ -346,6 +359,18 @@ static inline int wpas_dbus_register_bss(struct
> wpa_supplicant *wpa_s,
>  	return 0;
>  }
>  
> +static inline int wpas_dbus_unregister_sta(struct wpa_supplicant
> *wpa_s,
> +					   const u8 *sta)
> +{
> +	return 0;
> +}
> +
> +static inline int wpas_dbus_register_sta(struct wpa_supplicant
> *wpa_s,
> +					 const u8 *sta)
> +{
> +	return 0;
> +}
> +
>  static inline void wpas_dbus_signal_blob_added(struct wpa_supplicant
> *wpa_s,
>  					       const char *name)
>  {
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c
> b/wpa_supplicant/dbus/dbus_new_handlers.c
> index a3c98fadd..01a5bdb86 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.c
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.c
> @@ -22,6 +22,10 @@
>  #include "../bss.h"
>  #include "../scan.h"
>  #include "../autoscan.h"
> +#include "../ap.h"
> +#include "ap/hostapd.h"
> +#include "ap/sta_info.h"
> +#include "ap/ap_drv_ops.h"
>  #include "dbus_new_helpers.h"
>  #include "dbus_new.h"
>  #include "dbus_new_handlers.h"
> @@ -3854,6 +3858,315 @@ dbus_bool_t wpas_dbus_setter_iface_global(
>  }
>  
>  
> +/**
> + * wpas_dbus_getter_stas - Get connected stations for an interface
> + * @iter: Pointer to incoming dbus message iter
> + * @error: Location to store error on failure
> + * @user_data: Function specific data
> + * Returns: a list of stations
> + *
> + * Getter for "Stations" property.
> + */
> +dbus_bool_t wpas_dbus_getter_stas(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct wpa_supplicant *wpa_s = user_data;
> +	struct hostapd_data *hapd;
> +	struct sta_info *sta = NULL;
> +	char **paths = NULL;
> +	unsigned int i = 0, num = 0;
> +	dbus_bool_t success = FALSE;
> +
> +	if (!wpa_s->dbus_new_path) {
> +		dbus_set_error(error, DBUS_ERROR_FAILED,
> +			       "%s: no D-Bus interface", __func__);
> +		return FALSE;
> +	}
> +
> +	if (wpa_s->ap_iface) {
> +		hapd = wpa_s->ap_iface->bss[0];
> +		sta = hapd->sta_list;
> +		num = hapd->num_sta;
> +	}
> +
> +	paths = os_calloc(num, sizeof(char *));
> +	if (!paths) {
> +		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
> "no memory");
> +		return FALSE;
> +	}
> +
> +	/* Loop through scan results and append each result's object
> path */
> +	for (; sta; sta = sta->next) {
> +		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
> +		if (paths[i] == NULL) {
> +			dbus_set_error_const(error,
> DBUS_ERROR_NO_MEMORY,
> +					     "no memory");
> +			goto out;
> +		}
> +		/* Construct the object path for this BSS. */
> +		os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
> +			    "%s/" WPAS_DBUS_NEW_STAS_PART "/"
> COMPACT_MACSTR,
> +			    wpa_s->dbus_new_path, MAC2STR(sta-
> >addr));
> +	}
> +
> +	success = wpas_dbus_simple_array_property_getter(iter,
> +							 DBUS_TYPE_O
> BJECT_PATH,
> +							 paths, num,
> +							 error);
> +
> +out:
> +	while (i)
> +		os_free(paths[--i]);
> +	os_free(paths);
> +	return success;
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_sta_address - Return the BSSID of a connected
> station
> + * @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 "Address" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_address(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +
> +	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_array_property_getter(iter,
> DBUS_TYPE_BYTE,
> +						      sta->addr,
> ETH_ALEN,
> +						      error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_sta_aid - Return the AID of a connected station
> + * @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 "AID" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_aid(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +
> +	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT16,
> +						&sta->aid,
> +						error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_sta_flags - Return the flags of a connected
> station
> + * @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 "Flags" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_flags(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +
> +	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT32,
> +						&sta->flags,
> +						error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_sta_caps - Return the capabilities of a station
> + * @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 "Capabilities" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_caps(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +
> +	sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT16,
> +						&sta->capability,
> +						error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_rx_packets - Return the received packets for a
> station
> + * @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 "RxPackets" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_rx_packets(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +	struct hostap_sta_driver_data data;
> +	struct hostapd_data *hapd;
> +
> +	if (!args->wpa_s->ap_iface)
> +		return FALSE;
> +
> +	hapd = args->wpa_s->ap_iface->bss[0];
> +	sta = ap_get_sta(hapd, args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT64,
> +						&data.rx_packets,
> +						error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_tx_packets - Return the transmitted packets for
> a station
> + * @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 "TxPackets" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_tx_packets(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +	struct hostap_sta_driver_data data;
> +	struct hostapd_data *hapd;
> +
> +	if (!args->wpa_s->ap_iface)
> +		return FALSE;
> +
> +	hapd = args->wpa_s->ap_iface->bss[0];
> +	sta = ap_get_sta(hapd, args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT64,
> +						&data.tx_packets,
> +						error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_tx_bytes - Return the transmitted bytes for a
> station
> + * @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 "TxBytes" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_tx_bytes(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +	struct hostap_sta_driver_data data;
> +	struct hostapd_data *hapd;
> +
> +	if (!args->wpa_s->ap_iface)
> +		return FALSE;
> +
> +	hapd = args->wpa_s->ap_iface->bss[0];
> +	sta = ap_get_sta(hapd, args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT64,
> +						&data.tx_bytes,
> +						error);
> +}
> +
> +
> +/**
> + * wpas_dbus_getter_rx_bytes - Return the received bytes for a
> station
> + * @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 "RxBytes" property.
> + */
> +dbus_bool_t wpas_dbus_getter_sta_rx_bytes(
> +	const struct wpa_dbus_property_desc *property_desc,
> +	DBusMessageIter *iter, DBusError *error, void *user_data)
> +{
> +	struct sta_handler_args *args = user_data;
> +	struct sta_info *sta;
> +	struct hostap_sta_driver_data data;
> +	struct hostapd_data *hapd;
> +
> +	if (!args->wpa_s->ap_iface)
> +		return FALSE;
> +
> +	hapd = args->wpa_s->ap_iface->bss[0];
> +	sta = ap_get_sta(hapd, args->sta);
> +	if (!sta)
> +		return FALSE;
> +
> +        if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
> +		return FALSE;
> +
> +	return wpas_dbus_simple_property_getter(iter,
> DBUS_TYPE_UINT64,
> +						&data.rx_bytes,
> +						error);
> +}
> +
> +
>  static struct wpa_bss * get_bss_helper(struct bss_handler_args
> *args,
>  				       DBusError *error, const char
> *func_name)
>  {
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h
> b/wpa_supplicant/dbus/dbus_new_handlers.h
> index 26652ad3d..9a4f66171 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers.h
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.h
> @@ -22,6 +22,11 @@ struct bss_handler_args {
>  	unsigned int id;
>  };
>  
> +struct sta_handler_args {
> +	struct wpa_supplicant *wpa_s;
> +	const u8 *sta;
> +};
> +
>  dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
>  					     const int type,
>  					     const void *val,
> @@ -168,6 +173,15 @@ DECLARE_ACCESSOR(wpas_dbus_getter_networks);
>  DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_engine_path);
>  DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path);
>  DECLARE_ACCESSOR(wpas_dbus_getter_blobs);
> +DECLARE_ACCESSOR(wpas_dbus_getter_stas);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_address);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_flags);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_packets);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_packets);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_bytes);
> +DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_bytes);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_bssid);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_ssid);
>  DECLARE_ACCESSOR(wpas_dbus_getter_bss_privacy);
> diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
> index 83df04f39..b9bbe260a 100644
> --- a/wpa_supplicant/notify.c
> +++ b/wpa_supplicant/notify.c
> @@ -720,6 +720,9 @@ static void wpas_notify_ap_sta_authorized(struct
> wpa_supplicant *wpa_s,
>  		wpas_dbus_signal_p2p_peer_joined(wpa_s,
> p2p_dev_addr);
>  #endif /* CONFIG_P2P */
>  
> +	/* Unregister the station */
> +	wpas_dbus_register_sta(wpa_s, sta);
> +
>  	/* Notify listeners a new station has been authorized */
>  	wpas_dbus_signal_sta_authorized(wpa_s, sta);
>  }
> @@ -740,6 +743,9 @@ static void
> wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
>  
>  	/* Notify listeners a station has been deauthorized */
>  	wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
> +
> +	/* Unregister the station */
> +	wpas_dbus_unregister_sta(wpa_s, sta);
>  }
>  
>  


From jared.bents at rockwellcollins.com  Tue May  8 10:54:01 2018
From: jared.bents at rockwellcollins.com (Jared Bents)
Date: Tue, 8 May 2018 12:54:01 -0500
Subject: DN checks and CRL/Certificates dynamic updates
Message-ID: <CAM=7fbeEwOLbbgfkDF6f6SmcEen2YEjr8x6pguJceDV0etAczA@mail.gmail.com>

Hello,

I am just curious if anyone has looked into adding DN filtering
similar to Freeradius Server or being able to update the CRL without
restarting hostapd.  I'm trying to evaluate which of my two options of
modifying hostapd to add the features or switching to Freeradius
Server and applying a patch in their git pull requests for CA path
reload is the better path forward.

Thank you,
Jared


From andrew.shadura at collabora.co.uk  Thu May 10 10:07:11 2018
From: andrew.shadura at collabora.co.uk (Andrej Shadura)
Date: Thu, 10 May 2018 19:07:11 +0200
Subject: [PATCH] dbus: Expose connected stations on D-Bus
In-Reply-To: <44963247e199bb798406d34c1d0ebe397c421a0e.camel@redhat.com>
References: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>
 <44963247e199bb798406d34c1d0ebe397c421a0e.camel@redhat.com>
Message-ID: <6fc03360-f633-6b44-7892-063a2c29494f@collabora.co.uk>

On 08/05/18 18:53, Dan Williams wrote:
> On Mon, 2018-05-07 at 20:19 +0200, Andrej Shadura wrote:
>> From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>
>>
>> Make it possible to list connected stations in AP mode over D-Bus,
>> along
>> with some of their properties: rx/tx packets, bytes, capabilities,
>> etc.
> 
> It looks like this patch changes the signal signature of
> StaAuthorized/StaDeauthorized, is that correct?  That won't be
> backwards compatible with existing D-Bus clients and we should probably
> choose new signal names to allow old clients to continue working.

Hmm, indeed it does, and it probably shouldn?t. What would you call a
new signal with the new signature?

Mathieu, what applications rely on the proposed new signature of this
signal?

> Also, you'll want to update doc/dbus.doxygen with any changes you make
> to the D-Bus API, including additions.

Will do in the next iteration.

-- 
Cheers,
  Andrej

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/hostap/attachments/20180510/f13788b3/attachment.sig>

From slava.monich at jolla.com  Sat May 12 06:51:57 2018
From: slava.monich at jolla.com (Slava Monich)
Date: Sat, 12 May 2018 16:51:57 +0300
Subject: [PATCH] dbus: Expose connected stations on D-Bus
In-Reply-To: <6fc03360-f633-6b44-7892-063a2c29494f@collabora.co.uk>
References: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>
 <44963247e199bb798406d34c1d0ebe397c421a0e.camel@redhat.com>
 <6fc03360-f633-6b44-7892-063a2c29494f@collabora.co.uk>
Message-ID: <0530b7a2-41cd-25f6-4c26-ec1f67d377f5@jolla.com>

On 10/05/18 20:07, Andrej Shadura wrote:
> On 08/05/18 18:53, Dan Williams wrote:
>> On Mon, 2018-05-07 at 20:19 +0200, Andrej Shadura wrote:
>>> From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>
>>>
>>> Make it possible to list connected stations in AP mode over D-Bus,
>>> along
>>> with some of their properties: rx/tx packets, bytes, capabilities,
>>> etc.
>> It looks like this patch changes the signal signature of
>> StaAuthorized/StaDeauthorized, is that correct?  That won't be
>> backwards compatible with existing D-Bus clients and we should probably
>> choose new signal names to allow old clients to continue working.
> Hmm, indeed it does, and it probably shouldn?t. What would you call a
> new signal with the new signature?
>
> Mathieu, what applications rely on the proposed new signature of this
> signal?

I don't think


https://git.merproject.org/mer-core/libgsupplicant/blob/master/src/gsupplicant_interface.c#L1987


From slava.monich at jolla.com  Sat May 12 06:57:30 2018
From: slava.monich at jolla.com (Slava Monich)
Date: Sat, 12 May 2018 16:57:30 +0300
Subject: [PATCH] dbus: Expose connected stations on D-Bus
In-Reply-To: <6fc03360-f633-6b44-7892-063a2c29494f@collabora.co.uk>
References: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>
 <44963247e199bb798406d34c1d0ebe397c421a0e.camel@redhat.com>
 <6fc03360-f633-6b44-7892-063a2c29494f@collabora.co.uk>
Message-ID: <d94aff59-7d6b-2b2f-05cc-a2f388850149@jolla.com>

On 10/05/18 20:07, Andrej Shadura wrote:
> On 08/05/18 18:53, Dan Williams wrote:
>> On Mon, 2018-05-07 at 20:19 +0200, Andrej Shadura wrote:
>>> From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>
>>>
>>> Make it possible to list connected stations in AP mode over D-Bus,
>>> along
>>> with some of their properties: rx/tx packets, bytes, capabilities,
>>> etc.
>> It looks like this patch changes the signal signature of
>> StaAuthorized/StaDeauthorized, is that correct?  That won't be
>> backwards compatible with existing D-Bus clients and we should probably
>> choose new signal names to allow old clients to continue working.
> Hmm, indeed it does, and it probably shouldn?t. What would you call a
> new signal with the new signature?
>
> Mathieu, what applications rely on the proposed new signature of this
> signal?

Sorry for the spam, I accidentally hit the send button.

I don't think that Mathieu (or anyone else) knows the full list of 
applications relying on the current signature of this particular D-Bus 
signal. Here is an example of code which I'm sure Mathieu wasn't aware of:

https://git.merproject.org/mer-core/libgsupplicant/blob/master/src/gsupplicant_interface.c#L1987

Please don't break backward compatibility. It's not cool.

Cheers,
-Slava


From andrew.shadura at collabora.co.uk  Sat May 12 07:47:00 2018
From: andrew.shadura at collabora.co.uk (Andrej Shadura)
Date: Sat, 12 May 2018 16:47:00 +0200
Subject: [PATCH] dbus: Expose connected stations on D-Bus
In-Reply-To: <d94aff59-7d6b-2b2f-05cc-a2f388850149@jolla.com>
References: <20180507181949.7094-1-andrew.shadura@collabora.co.uk>
 <44963247e199bb798406d34c1d0ebe397c421a0e.camel@redhat.com>
 <6fc03360-f633-6b44-7892-063a2c29494f@collabora.co.uk>
 <d94aff59-7d6b-2b2f-05cc-a2f388850149@jolla.com>
Message-ID: <30c42628-c1f3-6dfd-a326-f47b54c075f1@collabora.co.uk>

On 12/05/18 15:57, Slava Monich wrote:
> On 10/05/18 20:07, Andrej Shadura wrote:
>> On 08/05/18 18:53, Dan Williams wrote:
>>> On Mon, 2018-05-07 at 20:19 +0200, Andrej Shadura wrote:
>>>> From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre at canonical.com>
>>>>
>>>> Make it possible to list connected stations in AP mode over D-Bus,
>>>> along
>>>> with some of their properties: rx/tx packets, bytes, capabilities,
>>>> etc.
>>> It looks like this patch changes the signal signature of
>>> StaAuthorized/StaDeauthorized, is that correct?? That won't be
>>> backwards compatible with existing D-Bus clients and we should probably
>>> choose new signal names to allow old clients to continue working.
>> Hmm, indeed it does, and it probably shouldn?t. What would you call a
>> new signal with the new signature?
>>
>> Mathieu, what applications rely on the proposed new signature of this
>> signal?
> 
> Sorry for the spam, I accidentally hit the send button.
> 
> I don't think that Mathieu (or anyone else) knows the full list of
> applications relying on the current signature of this particular D-Bus
> signal. Here is an example of code which I'm sure Mathieu wasn't aware of:
> 
> https://git.merproject.org/mer-core/libgsupplicant/blob/master/src/gsupplicant_interface.c#L1987
> 
> Please don't break backward compatibility. It's not cool.

Sure. My question was rather what relies on the new signature (Ubuntu
was shipping that patch for about two years I think).

I think Mathieu?s message didn?t reach the mailing list, so let me copy
his response here:

On 10/05/18 23:07, Mathieu Trudel-Lapierre wrote:
> I had written this a long while ago to use to inform GPS software,
> that would help triagulate using APs in range.
>
> FWIW, I won't need it at this point; feel free to rework the code to
> your heart's content if you can make use of it. :)

-- 
Cheers,
  Andrej


