[wpa_supplicant] Cumulative patch from 89bbe6f87

Bug: 130294744
Test: Device boots up and connects to WPA3/OWE wifi networks, run traffic.
Test: Able to turn on/off softap, associate wifi STA, run traffic.
Test: DPP test: act.py -c ../WifiDppConfig.json -tc WifiDppTest
Test: Regression test passed (Bug: 130312227)

89bbe6f87 EAP-pwd: Get rid of unnecessary allocation of temporary buffer
4396f74a3 EAP-pwd: Enforce 1 < rand,mask < r and rand+mask mod r > 1
72056f69a tests: Module tests for const_time_*() functions
16d4f1069 EAP-pwd: Check element x,y coordinates explicitly
8ad8585f9 EAP-pwd client: Verify received scalar and element
d63edfa90 EAP-pwd server: Detect reflection attacks
70ff850e8 EAP-pwd server: Verify received scalar and element
ac8fa9ef1 SAE: Fix confirm message validation in error cases
cff138b07 SAE: Use constant time operations in sae_test_pwd_seed_ffc()
f8f20717f SAE: Use const_time selection for PWE in FFC
90839597c SAE: Mask timing of MODP groups 22, 23, 24
362704dda SAE: Avoid branches in is_quadratic_residue_blind()
6513db3e9 SAE: Minimize timing differences in PWE derivation
aaf65feac EAP-pwd: Use constant time and memory access for finding the PWE
c93461c1d OpenSSL: Use constant time selection for crypto_bignum_legendre()
6e34f618d Add helper functions for constant time operations
d42c477cc OpenSSL: Use constant time operations for private bignums
242e85728 Extend domain_match and domain_suffix_match to allow list of values
dcc0ccd5b wolfSSL: Fix dNSName matching with domain_match and domain_suffix_match
83f13e4ff tests: Fix build without CONFIG_SAE
3580ed826 RADIUS server: Accept ERP keyName-NAI as user identity
bbde461d7 Fix a typo in the Multiple BSSID Index element ID define
1326cb765 DPP: Fix a regression in non-DPP, non-OpenSSL builds
db54db11a SAE: Reject unsuitable groups based on REVmd changes
6bb9d9a8d AP: Avoid NULL use with snprintf string
0a42f1ede scan: Use normal scans after connection failure
bbed23aee hostapd: Reduce minimum beacon interval from 15 to 10 TUs
048796715 OWE: Fix a possible memory leak on error path
277fa92b3 crypto: Fix unreachable code in tls_prf_sha1_md5()
3d93e26e6 tests: SAE test vector from IEEE P802.11-REVmd/D2.1, Annex J.10
e5711b618 Add a QCA vendor attribute to carry the reason for roaming
005585d60 nl80211: Add SAE, FT-SAE, FT-EAP-SHA384 AKMs in connect request
edcaf16f9 P2P: Enable HE for both 2G and 5G bands
822c756e8 MBO: Update connect params with new MBO attributes to driver
74f8e768f MBO: Always include Non-preferred Channel Report attribute in AssocReq
bd23daa8e DPP: Move GAS encapsulation into dpp_build_conf_req()
be609c6fc SAE: Fix commit message override with external authentication
9af1eea37 Prefer FT-SAE over FT-PSK if both are enabled
853bd19f2 Add more debug prints on suite selector selection
6d77014e7 Suite B: Prefer FT-EAP-SHA384 over WPA-EAP-SUITE-B-192
ab3aebcce SAE: Fix PMKSA cache entry search for FT-SAE case
253ce212e Add AKM info in the debug message noting PMKSA caching entry addition
6fe3f0f79 FT-SAE: Use PMK as XXKey in AP when SAE PMKSA caching is used
bcf190005 FT-SAE: Enable external auth support for FT-SAE also
6d14b98fc nl80211: Do not add WMM parameters when updating an existing STA entry
2ffd8076d FT/RRB: Pad RRB messages to at least minimum Ethernet frame length
555c93e2d FT/RRB: Add more debug prints for RRB message encryption/decryptiom
76fd782ab SAE: Reorder SAE and FT-SAE AKM selection to prefer the FT option
322d328e7 FT: Fix SAE + FT-SAE behavior in association parameter selection
87d8435cf DPP: Common configurator/bootstrapping data management
08dc8efd2 Fix memcpy regression in PMK handling
130444738 FILS: Fix KEK2 derivation for FILS+FT
bf84e78cb OpenSSL: Fix build with current BoringSSL
b750dde64 OWE: Move Association Response frame IE addition to appropriate place
10ec6a5f3 DPP2: PFS for PTK derivation
ecacd9ccd DPP2: Extend wpa_pmk_to_ptk() to support extra Z.x component in context
16a4e931f OWE: Allow Diffie-Hellman Parameter element to be included with DPP
808bdb308 Add TEST_FAIL() to aes_encrypt_init() with internal crypto
32f476066 TLS: Add support for RFC 5705 TLS exporter context with internal TLS
a916ff5cd Add support for an optional context parameter to TLS exporter
18015fc8a DPP2: Support new legacy+DPP config object credentials
dd6c59800 DPP: Support DPP and SAE in the same network profile
9305c2332 DPP: Clean up configuration parsing
f5db77504 Remove pending connect and sme-connect radio works on disconnect
c675397cc OpenSSL: Fix build with OpenSSL 1.0.2
ff5f54e15 SAE: Reduce queue wait time for pending Authentication frames
5e3a759cd SAE: Improved queuing policy for pending authentication frames
67b3bcc95 DPP2: Testing option for Config Object rejction
22f90b32f DPP2: Configuration Result message generation and processing
c98617b48 DPP2: Make DPP version number support available over control interface
673631b8a More robust timer_tick_enabled tracking
b5e57699a FILS+FT: STA mode validation of PMKR1Name in initial MD association
365366393 FILS+FT: AP mode processing of PMKR1Name in initial MD association
aabbdb818 FILS: Do not try to add PMKSA cache entry if caching is disabled
02bde9581 Vendor attribute to enable or disable TWT request support
4efade315 nl80211: Clear keys from heap memory before freeing it for get_seqnum
2b7fa0355 P2P: Fix ACS offloading behavior with p2p_no_group_iface=1
c6ec9759c nl80211: Exclude PMK when sending NL80211_CMD_DEL_PMKSA explicitly
0b4a906de DPP2: Protocol version indication
ce7effd08 DPP2: Build configuration flags for DPP version 2 support
bf0021ede Allow fragmentation/RTS threshold to be disabled explicitly
48102f65e Add a vendor subcommand QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG
f10a4af1b Add QCA vendor command/event and attributes for peer rate statistics
56a33496f Sync with mac80211-next.git include/uapi/linux/nl80211.h
841205a1c OpenSSL: Add 'check_cert_subject' support for TLS server
0173423f4 Use char pointers for EAP configuration parameters without length
cd6a5866e Remove forgotten os_strncpy() implementations
ca9efe113 roboswitch: Check some read operation results
9571f945c mesh: Check that SAE state initialization succeeded for PMKID check
fafad8527 defconfig: Enable DBus
6a8dee76d wpa_supplicant: Drop the old D-Bus interface support
954c535a5 DPP: Update wpa_supplicant configuration file after provisioning
4d379be4a Clarify AP mode Action frame handling
cc833a236 Minor cleanup to return after WNM Action frame handling
700b3f395 Move SA Query frame length check to the shared handler function
002edb630 Fix AP MLME in driver handling of FT and SA Query Action frames
1e653daa3 EAP-pwd server: Fix memory leak with salted passwords
96d6dfa8e SAE: Add Finite Cyclic Group field in status code 77 response
fda766010 EAP-pwd: Fix a memory leak in hunting-and-pecking loop
339dc8bd6 WPS: Allow SAE configuration to be added automatically for PSK
fc30f99b3 WPS: Allow AP SAE configuration to be added automatically for PSK
b9cd4f5e7 Vendor feature capability for TWT (Target Wake Time)
877502a6a Vendor attribute to indicate a set_blacklist of BSSID only as a hint
a9247bcdf Vendor attribute to configure HE testbed default capabilities
8a7510cc0 Vendor attribute to configure support to enable VHT in 2.4G band
8919ec616 Vendor attribute to configure HE OMI UL MU data disable
f21436158 SAE: Reuse previously generated PWE on a retry with the same STA
fd8308912 SAE: Reuse previously generated PWE on a retry with the same AP
a9af1da0b SAE: Enforce single use for anti-clogging tokens
ff9f40aee SAE: Process received commit message through a queue
a9fe13035 SAE: Enable only groups 19, 20, and 21 in station mode
941bad5ef SAE: Enable only group 19 by default in AP mode
b11fa98bc Add explicit checks for peer's DH public key
4a9531a75 bignum: Fix documentation for bignum_cmp_d()
611308365 defconfig: Enable IEEE 802.11w management frame protection (wpa_supplicant)
9515fa925 defconfig: enable IEEE 802.11r fast BSS transition (wpa_supplicant)
6b7a0da75 defconfig: Enable IEEE 802.11n and 802.11ac (wpa_supplicant)
467004d63 defconfig: Enable Hotspot 2.0 (wpa_supplicant)
ec52faa2b defconfig: Enable RSN on IBSS networks (wpa_supplicant)
67d99d2e0 defconfig: Remove obsolete notes about OpenSSL requirements for EAP-FAST
eafc5fec2 defconfig: Enable a handful of EAP methods (wpa_supplicant)
f64050da0 defconfig: Enable logging to file and syslog (wpa_supplicant)
ae5240db8 defconfig: Enable simple bgscan module (wpa_supplicant)
2d6d47219 defconfig: Enable AP (wpa_supplicant)
f87450a73 defconfig: Enable WPS (wpa_supplicant)
d989e67d0 defconfig: Fix typos in Wi-Fi Display description
c4eafad09 defconfig: Enable P2P and Wi-Fi Display (wpa_supplicant)
bf46c6fca defconfig: Add SAE (wpa_supplicant)
ca098ee45 defconfig: Add DPP (wpa_supplicant)
2f7bc0681 UBSan: Avoid a warning on unsigned integer overflow
bb05d0360 Fix a regression from VLAN assignment using WPA/WPA2 passphrase/PSK
429ed54a3 UBSan: Avoid a warning on signed left shift
b3957edbe UBSan: Split loop index decrementation into a separate step
5ac13f6d0 atheros: Avoid clang compiler warning on address of array check
aaa6b1498 Avoid compiler warning about potentially unaligned pointer value
cce974d36 UBSan: Define FST LLT macros without integer overflow
9140caf5f UBSan: Avoid integer overflow in a loop index counter
8fc22fdde UBSan: Avoid NULL pointer dereferences on an error path
43216777e UBSan: Avoid unsigned integer overflow in base64 encoding
fed7d8fcb UBSan: Avoid unsigned integer overflow in utf8_{,un}escape()
cc4cdefc7 UBSan: Avoid unnecessary warning
a9377bc38 UBSan: Avoid memcpy(ptr, NULL, 0)
5a23c2528 UBSan: Avoid an unsigned integer overflow warning
abde4eba4 UBSan: Pack MACsec peer id structure
c4fccfc7a UBSan: Avoid memcmp(ptr, NULL, 0)
1b85cad29 UBSan: Use typecast to avoid unsigned integer overflow
e3b5bd81b UBSan: Fix RRM beacon processing attempt without scan_info
01d01a311 UBSan: Avoid size_t variable overflow in control interface
ec2e7c4cf UBSan: Avoid unsigned integer overflow is throughput estimation
3b6b3ae58 Modify dl_list_for_each() to not use unaligned access with WPA_TRACE
1415d4b82 Multi-AP: Avoid memcpy(ptr, NULL, 0) in WPS Registrar initialization
2c129a1b7 Fix cipher suite selector default value in RSNE for DMG
239794018 Add new QCA vendor attributes for coex configuration
d939a8cb4 Add a vendor attribute for specifying ethernet protocol type
8682f384c hostapd: Add README-MULTI-AP
66819b07b hostapd: Support Multi-AP backhaul STA onboarding with WPS
83ebf5586 wpa_supplicant: Support Multi-AP backhaul STA onboarding with WPS
56a2d788f WPS: Add multi_ap_subelem to wps_build_wfa_ext()
bfcdac1c8 Multi-AP: Don't reject backhaul STA on fronthaul BSS
7ad7aa0e1 HS 2.0: Make hs20-osu-client SP and <FQDN> directories group writable
0f9632ceb mesh: More consistent checking of wpa_s->ifmsh in completion handler
2fae58fdc Fix wpa_psk_file parser error case handling
b0e91e387 SAE: VLAN assignment based on SAE Password Identifier
947b5a153 P2P: Stop listen state if Action frame TX is needed on another channel
b3e8ca65a P2P: Fix a typo in a debug message
464064c7e hostapd: Document openssl_ecdh_curves configuration parameter
31ee2992c Add QCA vendor subcmd/attribute to check wlan firmware state
3f8ceff54 Indicate wifi_generation in wpa_supplicant STATUS output
ccaf77476 Add HE Capabilities into ieee802_11_parse_elems()
5d68c0acd nl80211: (Re)Association Request frame IEs from association event
dbfa691df VLAN assignment based on used WPA/WPA2 passphrase/PSK
dd2aedeb5 HS 2.0 server: Add X-WFA-Hotspot20-Filtering header line to T&C

Change-Id: I4efde950845354673694f025ca07c3dddb6039e9
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 1834fc5..8bcd7ef 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -290,6 +290,9 @@
 NEED_JSON=y
 NEED_GAS_SERVER=y
 NEED_BASE64=y
+ifdef CONFIG_DPP2
+L_CFLAGS += -DCONFIG_DPP2
+endif
 endif
 
 ifdef CONFIG_OWE
@@ -1454,44 +1457,25 @@
 OBJS += ctrl_iface.c ctrl_iface_$(CONFIG_CTRL_IFACE).c
 endif
 
-ifdef CONFIG_CTRL_IFACE_DBUS
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
-DBUS_OBJS += dbus/dbus_old.c dbus/dbus_old_handlers.c
-ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_old_handlers_wps.c
-endif
-DBUS_OBJS += dbus/dbus_dict_helpers.c
-DBUS_CFLAGS += $(DBUS_INCLUDE)
-endif
-
 ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-DBUS_OBJS ?= dbus/dbus_dict_helpers.c
-DBUS_OBJS += dbus/dbus_new_helpers.c
-DBUS_OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
+L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
+OBJS += dbus/dbus_dict_helpers.c
+OBJS += dbus/dbus_new_helpers.c
+OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
+OBJS += dbus/dbus_common.c
 ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_new_handlers_wps.c
+OBJS += dbus/dbus_new_handlers_wps.c
 endif
 ifdef CONFIG_P2P
-DBUS_OBJS += dbus/dbus_new_handlers_p2p.c
+OBJS += dbus/dbus_new_handlers_p2p.c
 endif
 ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-DBUS_OBJS += dbus/dbus_new_introspect.c
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
+OBJS += dbus/dbus_new_introspect.c
+L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
 endif
-DBUS_CFLAGS += $(DBUS_INCLUDE)
+L_CFLAGS += $(DBUS_INCLUDE)
 endif
 
-ifdef DBUS
-DBUS_CFLAGS += -DCONFIG_DBUS
-DBUS_OBJS += dbus/dbus_common.c
-endif
-
-OBJS += $(DBUS_OBJS)
-L_CFLAGS += $(DBUS_CFLAGS)
-
 ifdef CONFIG_CTRL_IFACE_HIDL
 WPA_SUPPLICANT_USE_HIDL=y
 L_CFLAGS += -DCONFIG_HIDL -DCONFIG_CTRL_IFACE_HIDL
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index e55e062..e81238e 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -55,7 +55,6 @@
 ALL += systemd/wpa_supplicant@.service
 ALL += systemd/wpa_supplicant-nl80211@.service
 ALL += systemd/wpa_supplicant-wired@.service
-ALL += dbus/fi.epitest.hostap.WPASupplicant.service
 ALL += dbus/fi.w1.wpa_supplicant1.service
 ifdef CONFIG_BUILD_WPA_CLIENT_SO
 ALL += libwpa_client.so
@@ -292,6 +291,9 @@
 NEED_JSON=y
 NEED_GAS_SERVER=y
 NEED_BASE64=y
+ifdef CONFIG_DPP2
+CFLAGS += -DCONFIG_DPP2
+endif
 endif
 
 ifdef CONFIG_OWE
@@ -1576,35 +1578,17 @@
 OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
 endif
 
-ifdef CONFIG_CTRL_IFACE_DBUS
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
-DBUS_OBJS += dbus/dbus_old.o dbus/dbus_old_handlers.o
-ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_old_handlers_wps.o
-endif
-DBUS_OBJS += dbus/dbus_dict_helpers.o
-ifndef DBUS_LIBS
-DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
-endif
-ifndef DBUS_INCLUDE
-DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
-endif
-DBUS_CFLAGS += $(DBUS_INCLUDE)
-DBUS_INTERFACE=fi.epitest.hostap.WPASupplicant
-endif
-
 ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-DBUS=y
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-DBUS_OBJS ?= dbus/dbus_dict_helpers.o
-DBUS_OBJS += dbus/dbus_new_helpers.o
-DBUS_OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
+CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
+OBJS += dbus/dbus_dict_helpers.o
+OBJS += dbus/dbus_new_helpers.o
+OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
+OBJS += dbus/dbus_common.o
 ifdef CONFIG_WPS
-DBUS_OBJS += dbus/dbus_new_handlers_wps.o
+OBJS += dbus/dbus_new_handlers_wps.o
 endif
 ifdef CONFIG_P2P
-DBUS_OBJS += dbus/dbus_new_handlers_p2p.o
+OBJS += dbus/dbus_new_handlers_p2p.o
 endif
 ifndef DBUS_LIBS
 DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
@@ -1613,21 +1597,12 @@
 DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
 endif
 ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-DBUS_OBJS += dbus/dbus_new_introspect.o
-DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
+OBJS += dbus/dbus_new_introspect.o
+CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
 endif
-DBUS_CFLAGS += $(DBUS_INCLUDE)
-DBUS_INTERFACE=fi.w1.wpa_supplicant1
-endif
-
-ifdef DBUS
-DBUS_CFLAGS += -DCONFIG_DBUS
-DBUS_OBJS += dbus/dbus_common.o
-endif
-
-OBJS += $(DBUS_OBJS)
-CFLAGS += $(DBUS_CFLAGS)
+CFLAGS += $(DBUS_INCLUDE)
 LIBS += $(DBUS_LIBS)
+endif
 
 ifdef CONFIG_READLINE
 OBJS_c += ../src/utils/edit_readline.o
@@ -1990,13 +1965,11 @@
 endif
 
 %.service: %.service.in
-	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' \
-		-e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
 	@$(E) "  sed" $<
 
 %@.service: %.service.arg.in
-	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' \
-		-e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
 	@$(E) "  sed" $<
 
 wpa_supplicant.exe: wpa_supplicant
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 6db380a..b9b5d9d 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -88,9 +88,6 @@
 CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
 #CONFIG_EAP_FAST=y
 
 # EAP-GTC
@@ -327,10 +324,6 @@
 #CONFIG_NDIS_EVENTS_INTEGRATED=y
 #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
 
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
 # Add support for new DBus control interface
 # (fi.w1.hostap.wpa_supplicant1)
 #CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -487,8 +480,8 @@
 # Enable TDLS support
 CONFIG_TDLS=y
 
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
 # program to control the additional information exchanges in the messages.
 CONFIG_WIFI_DISPLAY=y
 
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 453c99d..4e19169 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -334,10 +334,13 @@
 			list[8] = -1;
 		}
 		conf->supported_rates = list;
+	}
+
 #ifdef CONFIG_IEEE80211AX
+	if (ssid->mode == WPAS_MODE_P2P_GO ||
+	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
 		conf->ieee80211ax = ssid->he;
 #endif /* CONFIG_IEEE80211AX */
-	}
 
 	bss->isolate = !wpa_s->conf->p2p_intra_bss;
 	bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 839dea2..a7ca41c 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2257,6 +2257,7 @@
 	{ STR_KEYe(private_key_passwd) },
 	{ STRe(dh_file) },
 	{ STRe(subject_match) },
+	{ STRe(check_cert_subject) },
 	{ STRe(altsubject_match) },
 	{ STRe(domain_suffix_match) },
 	{ STRe(domain_match) },
@@ -2267,6 +2268,7 @@
 	{ STR_KEYe(private_key2_passwd) },
 	{ STRe(dh_file2) },
 	{ STRe(subject_match2) },
+	{ STRe(check_cert_subject2) },
 	{ STRe(altsubject_match2) },
 	{ STRe(domain_suffix_match2) },
 	{ STRe(domain_match2) },
@@ -2525,6 +2527,7 @@
 	str_clear_free(eap->private_key_passwd);
 	os_free(eap->dh_file);
 	os_free(eap->subject_match);
+	os_free(eap->check_cert_subject);
 	os_free(eap->altsubject_match);
 	os_free(eap->domain_suffix_match);
 	os_free(eap->domain_match);
@@ -2535,6 +2538,7 @@
 	str_clear_free(eap->private_key2_passwd);
 	os_free(eap->dh_file2);
 	os_free(eap->subject_match2);
+	os_free(eap->check_cert_subject2);
 	os_free(eap->altsubject_match2);
 	os_free(eap->domain_suffix_match2);
 	os_free(eap->domain_match2);
@@ -4752,6 +4756,7 @@
 	{ FUNC(os_version), CFG_CHANGED_OS_VERSION },
 	{ STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
 	{ INT_RANGE(wps_cred_processing, 0, 2), 0 },
+	{ INT_RANGE(wps_cred_add_sae, 0, 1), 0 },
 	{ FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 4b84200..95817ff 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -745,6 +745,16 @@
 	 */
 	int wps_cred_processing;
 
+	/**
+	 * wps_cred_add_sae - Whether to enable SAE automatically for WPS
+	 *
+	 * 0 = only add the explicitly listed WPA2-PSK configuration
+	 * 1 = add both the WPA2-PSK and SAE configuration and enable PMF so
+	 *     that the station gets configured in WPA3-Personal transition mode
+	 *     (supports both WPA2-Personal (PSK) and WPA3-Personal (SAE) APs).
+	 */
+	int wps_cred_add_sae;
+
 #define MAX_SEC_DEVICE_TYPES 5
 	/**
 	 * sec_device_types - Secondary Device Types (P2P)
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 5fcad36..2c6035c 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -782,6 +782,7 @@
 	STR(private_key_passwd);
 	STR(dh_file);
 	STR(subject_match);
+	STR(check_cert_subject);
 	STR(altsubject_match);
 	STR(domain_suffix_match);
 	STR(domain_match);
@@ -792,6 +793,7 @@
 	STR(private_key2_passwd);
 	STR(dh_file2);
 	STR(subject_match2);
+	STR(check_cert_subject2);
 	STR(altsubject_match2);
 	STR(domain_suffix_match2);
 	STR(domain_match2);
@@ -1187,6 +1189,9 @@
 	if (config->wps_cred_processing)
 		fprintf(f, "wps_cred_processing=%d\n",
 			config->wps_cred_processing);
+	if (config->wps_cred_add_sae)
+		fprintf(f, "wps_cred_add_sae=%d\n",
+			config->wps_cred_add_sae);
 	if (config->wps_vendor_ext_m1) {
 		int i, len = wpabuf_len(config->wps_vendor_ext_m1);
 		const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1);
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index 0ce1830..6328e91 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -255,6 +255,8 @@
 		errors++;
 	wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
 				  &config->wps_cred_processing);
+	wpa_config_read_reg_dword(hk, TEXT("wps_cred_add_sae"),
+				  &config->wps_cred_add_sae);
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
 	config->p2p_ssid_postfix = wpa_config_read_reg_string(
@@ -604,6 +606,8 @@
 	}
 	wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
 				   config->wps_cred_processing, 0);
+	wpa_config_write_reg_dword(hk, TEXT("wps_cred_add_sae"),
+				   config->wps_cred_add_sae, 0);
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
 	wpa_config_write_reg_string(hk, "p2p_ssid_postfix",
@@ -892,6 +896,7 @@
 	STR(private_key_passwd);
 	STR(dh_file);
 	STR(subject_match);
+	STR(check_cert_subject);
 	STR(altsubject_match);
 	STR(ca_cert2);
 	STR(ca_path2);
@@ -900,6 +905,7 @@
 	STR(private_key2_passwd);
 	STR(dh_file2);
 	STR(subject_match2);
+	STR(check_cert_subject2);
 	STR(altsubject_match2);
 	STR(phase1);
 	STR(phase2);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index a0db9e4..564f32b 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1168,8 +1168,11 @@
 #ifdef CONFIG_AP
 	u8 *_p2p_dev_addr = NULL;
 #endif /* CONFIG_AP */
+	char *pos;
+	int multi_ap = 0;
 
-	if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
+	if (!cmd || os_strcmp(cmd, "any") == 0 ||
+	    os_strncmp(cmd, "any ", 4) == 0) {
 		_bssid = NULL;
 #ifdef CONFIG_P2P
 	} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
@@ -1181,18 +1184,29 @@
 		}
 		_p2p_dev_addr = p2p_dev_addr;
 #endif /* CONFIG_P2P */
+	} else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
+		_bssid = NULL;
+		multi_ap = atoi(cmd + 9);
 	} else if (hwaddr_aton(cmd, bssid)) {
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
 			   cmd);
 		return -1;
 	}
 
+	if (cmd) {
+		pos = os_strstr(cmd, " multi_ap=");
+		if (pos) {
+			pos += 10;
+			multi_ap = atoi(pos);
+		}
+	}
+
 #ifdef CONFIG_AP
 	if (wpa_s->ap_iface)
 		return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
 #endif /* CONFIG_AP */
 
-	return wpas_wps_start_pbc(wpa_s, _bssid, 0);
+	return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
 }
 
 
@@ -2118,6 +2132,18 @@
 			pos += ret;
 		}
 
+		if (wpa_s->connection_set &&
+		    (wpa_s->connection_ht || wpa_s->connection_vht ||
+		     wpa_s->connection_he)) {
+			ret = os_snprintf(pos, end - pos,
+					  "wifi_generation=%u\n",
+					  wpa_s->connection_he ? 6 :
+					  (wpa_s->connection_vht ? 5 : 4));
+			if (os_snprintf_error(end - pos, ret))
+				return pos - buf;
+			pos += ret;
+		}
+
 #ifdef CONFIG_AP
 		if (wpa_s->ap_iface) {
 			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
@@ -4417,6 +4443,19 @@
 		return res;
 	}
 
+#ifdef CONFIG_DPP
+	if (os_strcmp(field, "dpp") == 0) {
+#ifdef CONFIG_DPP2
+		res = os_snprintf(buf, buflen, "DPP=2");
+#else /* CONFIG_DPP2 */
+		res = os_snprintf(buf, buflen, "DPP=1");
+#endif /* CONFIG_DPP2 */
+		if (os_snprintf_error(buflen, res))
+			return -1;
+		return res;
+	}
+#endif /* CONFIG_DPP */
+
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
 		   field);
 
@@ -5057,10 +5096,11 @@
 		bss = NULL;
 		dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
 		{
-			if (i-- == 0) {
+			if (i == 0) {
 				bss = tmp;
 				break;
 			}
+			i--;
 		}
 	}
 
@@ -6391,6 +6431,8 @@
 			wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211ANY;
 			wpa_s->p2p_go_do_acs = 1;
 		}
+	} else {
+		wpa_s->p2p_go_do_acs = 0;
 	}
 #endif /* CONFIG_ACS */
 
@@ -10634,7 +10676,7 @@
 	} else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
 		int res;
 
-		res = wpas_dpp_bootstrap_gen(wpa_s, buf + 18);
+		res = dpp_bootstrap_gen(wpa_s->dpp, buf + 18);
 		if (res < 0) {
 			reply_len = -1;
 		} else {
@@ -10643,12 +10685,12 @@
 				reply_len = -1;
 		}
 	} else if (os_strncmp(buf, "DPP_BOOTSTRAP_REMOVE ", 21) == 0) {
-		if (wpas_dpp_bootstrap_remove(wpa_s, buf + 21) < 0)
+		if (dpp_bootstrap_remove(wpa_s->dpp, buf + 21) < 0)
 			reply_len = -1;
 	} else if (os_strncmp(buf, "DPP_BOOTSTRAP_GET_URI ", 22) == 0) {
 		const char *uri;
 
-		uri = wpas_dpp_bootstrap_get_uri(wpa_s, atoi(buf + 22));
+		uri = dpp_bootstrap_get_uri(wpa_s->dpp, atoi(buf + 22));
 		if (!uri) {
 			reply_len = -1;
 		} else {
@@ -10657,8 +10699,8 @@
 				reply_len = -1;
 		}
 	} else if (os_strncmp(buf, "DPP_BOOTSTRAP_INFO ", 19) == 0) {
-		reply_len = wpas_dpp_bootstrap_info(wpa_s, atoi(buf + 19),
-						    reply, reply_size);
+		reply_len = dpp_bootstrap_info(wpa_s->dpp, atoi(buf + 19),
+					       reply, reply_size);
 	} else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
 		if (wpas_dpp_auth_init(wpa_s, buf + 13) < 0)
 			reply_len = -1;
@@ -10671,7 +10713,7 @@
 	} else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
 		int res;
 
-		res = wpas_dpp_configurator_add(wpa_s, buf + 20);
+		res = dpp_configurator_add(wpa_s->dpp, buf + 20);
 		if (res < 0) {
 			reply_len = -1;
 		} else {
@@ -10680,14 +10722,15 @@
 				reply_len = -1;
 		}
 	} else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
-		if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
+		if (dpp_configurator_remove(wpa_s->dpp, buf + 24) < 0)
 			reply_len = -1;
 	} else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
 		if (wpas_dpp_configurator_sign(wpa_s, buf + 21) < 0)
 			reply_len = -1;
 	} else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
-		reply_len = wpas_dpp_configurator_get_key(wpa_s, atoi(buf + 25),
-							  reply, reply_size);
+		reply_len = dpp_configurator_get_key_id(wpa_s->dpp,
+							atoi(buf + 25),
+							reply, reply_size);
 	} else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
 		int res;
 
diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile
index f355ebe..4d87004 100644
--- a/wpa_supplicant/dbus/Makefile
+++ b/wpa_supplicant/dbus/Makefile
@@ -36,7 +36,6 @@
 endif
 
 CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS
 
 ifndef DBUS_LIBS
 DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
@@ -54,8 +53,6 @@
 
 LIB_OBJS= \
 	dbus_common.o \
-	dbus_old.o \
-	dbus_old_handlers.o \
 	dbus_new.o \
 	dbus_new_handlers.o \
 	dbus_new_helpers.o \
@@ -63,7 +60,6 @@
 	dbus_dict_helpers.o
 
 ifdef CONFIG_WPS
-LIB_OBJS += dbus_old_handlers_wps.o
 LIB_OBJS += dbus_new_handlers_wps.o
 endif
 
diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
index 382dcb3..e81b495 100644
--- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
+++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
@@ -3,11 +3,6 @@
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
 <busconfig>
         <policy user="root">
-                <allow own="fi.epitest.hostap.WPASupplicant"/>
-
-                <allow send_destination="fi.epitest.hostap.WPASupplicant"/>
-                <allow send_interface="fi.epitest.hostap.WPASupplicant"/>
-
                 <allow own="fi.w1.wpa_supplicant1"/>
 
                 <allow send_destination="fi.w1.wpa_supplicant1"/>
@@ -15,9 +10,6 @@
                 <allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
         </policy>
         <policy context="default">
-                <deny own="fi.epitest.hostap.WPASupplicant"/>
-                <deny send_destination="fi.epitest.hostap.WPASupplicant"/>
-
                 <deny own="fi.w1.wpa_supplicant1"/>
                 <deny send_destination="fi.w1.wpa_supplicant1"/>
                 <deny receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
diff --git a/wpa_supplicant/dbus/dbus_common.c b/wpa_supplicant/dbus/dbus_common.c
index 7ef6cad..efa6c7b 100644
--- a/wpa_supplicant/dbus/dbus_common.c
+++ b/wpa_supplicant/dbus/dbus_common.c
@@ -16,7 +16,6 @@
 #include "dbus_common.h"
 #include "dbus_common_i.h"
 #include "dbus_new.h"
-#include "dbus_old.h"
 #include "../wpa_supplicant_i.h"
 
 
@@ -351,9 +350,6 @@
 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 	    wpas_dbus_ctrl_iface_init(priv) < 0 ||
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-#ifdef CONFIG_CTRL_IFACE_DBUS
-	    wpa_supplicant_dbus_ctrl_iface_init(priv) < 0 ||
-#endif /* CONFIG_CTRL_IFACE_DBUS */
 	    wpas_dbus_init_common_finish(priv) < 0) {
 		wpas_dbus_deinit(priv);
 		return NULL;
@@ -372,9 +368,5 @@
 	wpas_dbus_ctrl_iface_deinit(priv);
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
-#ifdef CONFIG_CTRL_IFACE_DBUS
-	/* TODO: is any deinit needed? */
-#endif /* CONFIG_CTRL_IFACE_DBUS */
-
 	wpas_dbus_deinit_common(priv);
 }
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index 19c1a61..1594daf 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -293,7 +293,7 @@
 					message, "invalid PIN");
 		}
 	} else {
-		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
+		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
 	}
 
 	if (ret < 0) {
diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
deleted file mode 100644
index 88227af..0000000
--- a/wpa_supplicant/dbus/dbus_old.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "eloop.h"
-#include "wps/wps.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../bss.h"
-#include "dbus_old.h"
-#include "dbus_old_handlers.h"
-#include "dbus_common_i.h"
-
-
-/**
- * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
- * @path: The dbus object path
- * @network: (out) the configured network this object path refers to, if any
- * @bssid: (out) the scanned bssid this object path refers to, if any
- * Returns: The object path of the network interface this path refers to
- *
- * For a given object path, decomposes the object path into object id, network,
- * and BSSID parts, if those parts exist.
- */
-char * wpas_dbus_decompose_object_path(const char *path, char **network,
-				       char **bssid)
-{
-	const unsigned int dev_path_prefix_len =
-		strlen(WPAS_DBUS_PATH_INTERFACES "/");
-	char *obj_path_only;
-	char *next_sep;
-
-	/* Be a bit paranoid about path */
-	if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/",
-			     dev_path_prefix_len))
-		return NULL;
-
-	/* Ensure there's something at the end of the path */
-	if ((path + dev_path_prefix_len)[0] == '\0')
-		return NULL;
-
-	obj_path_only = os_strdup(path);
-	if (obj_path_only == NULL)
-		return NULL;
-
-	next_sep = strchr(obj_path_only + dev_path_prefix_len, '/');
-	if (next_sep != NULL) {
-		const char *net_part = strstr(next_sep,
-					      WPAS_DBUS_NETWORKS_PART "/");
-		const char *bssid_part = strstr(next_sep,
-						WPAS_DBUS_BSSIDS_PART "/");
-
-		if (network && net_part) {
-			/* Deal with a request for a configured network */
-			const char *net_name = net_part +
-				strlen(WPAS_DBUS_NETWORKS_PART "/");
-			*network = NULL;
-			if (strlen(net_name))
-				*network = os_strdup(net_name);
-		} else if (bssid && bssid_part) {
-			/* Deal with a request for a scanned BSSID */
-			const char *bssid_name = bssid_part +
-				strlen(WPAS_DBUS_BSSIDS_PART "/");
-			if (strlen(bssid_name))
-				*bssid = os_strdup(bssid_name);
-			else
-				*bssid = NULL;
-		}
-
-		/* Cut off interface object path before "/" */
-		*next_sep = '\0';
-	}
-
-	return obj_path_only;
-}
-
-
-/**
- * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: A dbus error message
- *
- * Convenience function to create and return an invalid interface error
- */
-DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message)
-{
-	return dbus_message_new_error(
-		message, WPAS_ERROR_INVALID_IFACE,
-		"wpa_supplicant knows nothing about this interface.");
-}
-
-
-/**
- * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid network error
- */
-DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message)
-{
-	return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK,
-				      "The requested network does not exist.");
-}
-
-
-/**
- * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid bssid error
- */
-static DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message)
-{
-	return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID,
-				      "The BSSID requested was invalid.");
-}
-
-
-/**
- * wpas_dispatch_network_method - dispatch messages for configured networks
- * @message: the incoming dbus message
- * @wpa_s: a network interface's data
- * @network_id: id of the configured network we're interested in
- * Returns: a reply dbus message, or a dbus error message
- *
- * This function dispatches all incoming dbus messages for configured networks.
- */
-static DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
-						  struct wpa_supplicant *wpa_s,
-						  int network_id)
-{
-	DBusMessage *reply = NULL;
-	const char *method = dbus_message_get_member(message);
-	struct wpa_ssid *ssid;
-
-	ssid = wpa_config_get_network(wpa_s->conf, network_id);
-	if (ssid == NULL)
-		return wpas_dbus_new_invalid_network_error(message);
-
-	if (!strcmp(method, "set"))
-		reply = wpas_dbus_iface_set_network(message, wpa_s, ssid);
-	else if (!strcmp(method, "enable"))
-		reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid);
-	else if (!strcmp(method, "disable"))
-		reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid);
-
-	return reply;
-}
-
-
-/**
- * wpas_dispatch_bssid_method - dispatch messages for scanned networks
- * @message: the incoming dbus message
- * @wpa_s: a network interface's data
- * @bssid: bssid of the scanned network we're interested in
- * Returns: a reply dbus message, or a dbus error message
- *
- * This function dispatches all incoming dbus messages for scanned networks.
- */
-static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message,
-						struct wpa_supplicant *wpa_s,
-						const char *bssid_txt)
-{
-	u8 bssid[ETH_ALEN];
-	struct wpa_bss *bss;
-
-	if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0)
-		return wpas_dbus_new_invalid_bssid_error(message);
-
-	bss = wpa_bss_get_bssid(wpa_s, bssid);
-	if (bss == NULL)
-		return wpas_dbus_new_invalid_bssid_error(message);
-
-	/* Dispatch the method call against the scanned bssid */
-	if (os_strcmp(dbus_message_get_member(message), "properties") == 0)
-		return wpas_dbus_bssid_properties(message, wpa_s, bss);
-
-	return NULL;
-}
-
-
-/**
- * wpas_iface_message_handler - Dispatch messages for interfaces or networks
- * @connection: Connection to the system message bus
- * @message: An incoming dbus message
- * @user_data: A pointer to a dbus control interface data structure
- * Returns: Whether or not the message was handled
- *
- * This function dispatches all incoming dbus messages for network interfaces,
- * or objects owned by them, such as scanned BSSIDs and configured networks.
- */
-static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
-						    DBusMessage *message,
-						    void *user_data)
-{
-	struct wpa_supplicant *wpa_s = user_data;
-	const char *method = dbus_message_get_member(message);
-	const char *path = dbus_message_get_path(message);
-	const char *msg_interface = dbus_message_get_interface(message);
-	char *iface_obj_path = NULL;
-	char *network = NULL;
-	char *bssid = NULL;
-	DBusMessage *reply = NULL;
-
-	/* Caller must specify a message interface */
-	if (!msg_interface)
-		goto out;
-
-	wpa_printf(MSG_MSGDUMP, "dbus[old/iface]: %s.%s (%s) [%s]",
-		   msg_interface, method, path,
-		   dbus_message_get_signature(message));
-
-	iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
-							 &bssid);
-	if (iface_obj_path == NULL) {
-		reply = wpas_dbus_new_invalid_iface_error(message);
-		goto out;
-	}
-
-	/* Make sure the message's object path actually refers to the
-	 * wpa_supplicant structure it's supposed to (which is wpa_s)
-	 */
-	if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
-						  iface_obj_path) != wpa_s) {
-		reply = wpas_dbus_new_invalid_iface_error(message);
-		goto out;
-	}
-
-	if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
-		/* A method for one of this interface's configured networks */
-		int nid = strtoul(network, NULL, 10);
-
-		if (errno != EINVAL)
-			reply = wpas_dispatch_network_method(message, wpa_s,
-							     nid);
-		else
-			reply = wpas_dbus_new_invalid_network_error(message);
-	} else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) {
-		/* A method for one of this interface's scanned BSSIDs */
-		reply = wpas_dispatch_bssid_method(message, wpa_s, bssid);
-	} else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) {
-		/* A method for an interface only. */
-		if (!strcmp(method, "scan"))
-			reply = wpas_dbus_iface_scan(message, wpa_s);
-		else if (!strcmp(method, "scanResults"))
-			reply = wpas_dbus_iface_scan_results(message, wpa_s);
-		else if (!strcmp(method, "addNetwork"))
-			reply = wpas_dbus_iface_add_network(message, wpa_s);
-		else if (!strcmp(method, "removeNetwork"))
-			reply = wpas_dbus_iface_remove_network(message, wpa_s);
-		else if (!strcmp(method, "selectNetwork"))
-			reply = wpas_dbus_iface_select_network(message, wpa_s);
-		else if (!strcmp(method, "capabilities"))
-			reply = wpas_dbus_iface_capabilities(message, wpa_s);
-		else if (!strcmp(method, "disconnect"))
-			reply = wpas_dbus_iface_disconnect(message, wpa_s);
-		else if (!strcmp(method, "setAPScan"))
-			reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
-		else if (!strcmp(method, "setSmartcardModules"))
-			reply = wpas_dbus_iface_set_smartcard_modules(message,
-								      wpa_s);
-		else if (!strcmp(method, "state"))
-			reply = wpas_dbus_iface_get_state(message, wpa_s);
-		else if (!strcmp(method, "scanning"))
-			reply = wpas_dbus_iface_get_scanning(message, wpa_s);
-#ifndef CONFIG_NO_CONFIG_BLOBS
-		else if (!strcmp(method, "setBlobs"))
-			reply = wpas_dbus_iface_set_blobs(message, wpa_s);
-		else if (!strcmp(method, "removeBlobs"))
-			reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-#ifdef CONFIG_WPS
-		else if (os_strcmp(method, "wpsPbc") == 0)
-			reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
-		else if (os_strcmp(method, "wpsPin") == 0)
-			reply = wpas_dbus_iface_wps_pin(message, wpa_s);
-		else if (os_strcmp(method, "wpsReg") == 0)
-			reply = wpas_dbus_iface_wps_reg(message, wpa_s);
-#endif /* CONFIG_WPS */
-		else if (os_strcmp(method, "flush") == 0)
-			reply = wpas_dbus_iface_flush(message, wpa_s);
-	}
-
-	/* If the message was handled, send back the reply */
-out:
-	if (reply) {
-		if (!dbus_message_get_no_reply(message))
-			dbus_connection_send(connection, reply, NULL);
-		dbus_message_unref(reply);
-	}
-
-	os_free(iface_obj_path);
-	os_free(network);
-	os_free(bssid);
-	return reply ? DBUS_HANDLER_RESULT_HANDLED :
-		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-/**
- * wpas_message_handler - dispatch incoming dbus messages
- * @connection: connection to the system message bus
- * @message: an incoming dbus message
- * @user_data: a pointer to a dbus control interface data structure
- * Returns: whether or not the message was handled
- *
- * This function dispatches all incoming dbus messages to the correct
- * handlers, depending on what the message's target object path is,
- * and what the method call is.
- */
-static DBusHandlerResult wpas_message_handler(DBusConnection *connection,
-	DBusMessage *message, void *user_data)
-{
-	struct wpas_dbus_priv *ctrl_iface = user_data;
-	const char *method;
-	const char *path;
-	const char *msg_interface;
-	DBusMessage *reply = NULL;
-
-	method = dbus_message_get_member(message);
-	path = dbus_message_get_path(message);
-	msg_interface = dbus_message_get_interface(message);
-	if (!method || !path || !ctrl_iface || !msg_interface)
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-	wpa_printf(MSG_MSGDUMP, "dbus[old]: %s.%s (%s) [%s]",
-		   msg_interface, method, path,
-		   dbus_message_get_signature(message));
-
-	/* Validate the method interface */
-	if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0)
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-	if (!strcmp(path, WPAS_DBUS_PATH)) {
-		/* dispatch methods against our global dbus interface here */
-		if (!strcmp(method, "addInterface")) {
-			reply = wpas_dbus_global_add_interface(
-				message, ctrl_iface->global);
-		} else if (!strcmp(method, "removeInterface")) {
-			reply = wpas_dbus_global_remove_interface(
-				message, ctrl_iface->global);
-		} else if (!strcmp(method, "getInterface")) {
-			reply = wpas_dbus_global_get_interface(
-				message, ctrl_iface->global);
-		} else if (!strcmp(method, "setDebugParams")) {
-			reply = wpas_dbus_global_set_debugparams(
-				message, ctrl_iface->global);
-		}
-	}
-
-	/* If the message was handled, send back the reply */
-	if (reply) {
-		if (!dbus_message_get_no_reply(message))
-			dbus_connection_send(connection, reply, NULL);
-		dbus_message_unref(reply);
-	}
-
-	return reply ? DBUS_HANDLER_RESULT_HANDLED :
-		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-/**
- * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
- * @wpa_s: %wpa_supplicant network interface data
- * Returns: 0 on success, -1 on failure
- *
- * Notify listeners that this interface has updated scan results.
- */
-void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
-	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
-	DBusMessage *_signal;
-
-	/* Do nothing if the control interface is not turned on */
-	if (iface == NULL || !wpa_s->dbus_path)
-		return;
-
-	_signal = dbus_message_new_signal(wpa_s->dbus_path,
-					  WPAS_DBUS_IFACE_INTERFACE,
-					  "ScanResultsAvailable");
-	if (_signal == NULL) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: Not enough memory to send scan results signal");
-		return;
-	}
-	dbus_connection_send(iface->con, _signal, NULL);
-	dbus_message_unref(_signal);
-}
-
-
-/**
- * wpa_supplicant_dbus_notify_state_change - Send a state change signal
- * @wpa_s: %wpa_supplicant network interface data
- * @new_state: new state wpa_supplicant is entering
- * @old_state: old state wpa_supplicant is leaving
- * Returns: 0 on success, -1 on failure
- *
- * Notify listeners that wpa_supplicant has changed state
- */
-void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
-					     enum wpa_states new_state,
-					     enum wpa_states old_state)
-{
-	struct wpas_dbus_priv *iface;
-	DBusMessage *_signal = NULL;
-	const char *new_state_str, *old_state_str;
-
-	if (wpa_s->dbus_path == NULL)
-		return; /* Skip signal since D-Bus setup is not yet ready */
-
-	/* Do nothing if the control interface is not turned on */
-	if (wpa_s->global == NULL)
-		return;
-	iface = wpa_s->global->dbus;
-	if (iface == NULL)
-		return;
-
-	/* Only send signal if state really changed */
-	if (new_state == old_state)
-		return;
-
-	_signal = dbus_message_new_signal(wpa_s->dbus_path,
-					  WPAS_DBUS_IFACE_INTERFACE,
-					  "StateChange");
-	if (_signal == NULL) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: %s: could not create dbus signal; likely out of memory",
-			   __func__);
-		return;
-	}
-
-	new_state_str = wpa_supplicant_state_txt(new_state);
-	old_state_str = wpa_supplicant_state_txt(old_state);
-
-	if (!dbus_message_append_args(_signal,
-				      DBUS_TYPE_STRING, &new_state_str,
-				      DBUS_TYPE_STRING, &old_state_str,
-				      DBUS_TYPE_INVALID)) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: %s: Not enough memory to construct state change signal",
-			   __func__);
-		goto out;
-	}
-
-	dbus_connection_send(iface->con, _signal, NULL);
-
-out:
-	dbus_message_unref(_signal);
-}
-
-
-/**
- * wpa_supplicant_dbus_notify_scanning - send scanning status
- * @wpa_s: %wpa_supplicant network interface data
- * Returns: 0 on success, -1 on failure
- *
- * Notify listeners of interface scanning state changes
- */
-void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
-{
-	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
-	DBusMessage *_signal;
-	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-
-	/* Do nothing if the control interface is not turned on */
-	if (iface == NULL || !wpa_s->dbus_path)
-		return;
-
-	_signal = dbus_message_new_signal(wpa_s->dbus_path,
-					  WPAS_DBUS_IFACE_INTERFACE,
-					  "Scanning");
-	if (_signal == NULL) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: Not enough memory to send scan results signal");
-		return;
-	}
-
-	if (dbus_message_append_args(_signal,
-				     DBUS_TYPE_BOOLEAN, &scanning,
-				     DBUS_TYPE_INVALID)) {
-		dbus_connection_send(iface->con, _signal, NULL);
-	} else {
-		wpa_printf(MSG_ERROR,
-			   "dbus: Not enough memory to construct signal");
-	}
-	dbus_message_unref(_signal);
-}
-
-
-#ifdef CONFIG_WPS
-void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
-					 const struct wps_credential *cred)
-{
-	struct wpas_dbus_priv *iface;
-	DBusMessage *_signal = NULL;
-
-	/* Do nothing if the control interface is not turned on */
-	if (wpa_s->global == NULL)
-		return;
-	iface = wpa_s->global->dbus;
-	if (iface == NULL || !wpa_s->dbus_path)
-		return;
-
-	_signal = dbus_message_new_signal(wpa_s->dbus_path,
-					  WPAS_DBUS_IFACE_INTERFACE,
-					  "WpsCred");
-	if (_signal == NULL) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: %s: Could not create dbus signal; likely out of memory",
-			   __func__);
-		return;
-	}
-
-	if (!dbus_message_append_args(_signal,
-				      DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
-				      &cred->cred_attr, cred->cred_attr_len,
-				      DBUS_TYPE_INVALID)) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: %s: Not enough memory to construct signal",
-			   __func__);
-		goto out;
-	}
-
-	dbus_connection_send(iface->con, _signal, NULL);
-
-out:
-	dbus_message_unref(_signal);
-}
-#else /* CONFIG_WPS */
-void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
-					 const struct wps_credential *cred)
-{
-}
-#endif /* CONFIG_WPS */
-
-void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
-					      int depth, const char *subject,
-					      const char *cert_hash,
-					      const struct wpabuf *cert)
-{
-	struct wpas_dbus_priv *iface;
-	DBusMessage *_signal = NULL;
-	const char *hash;
-	const char *cert_hex;
-	int cert_hex_len;
-
-	/* Do nothing if the control interface is not turned on */
-	if (wpa_s->global == NULL)
-		return;
-	iface = wpa_s->global->dbus;
-	if (iface == NULL || !wpa_s->dbus_path)
-		return;
-
-	_signal = dbus_message_new_signal(wpa_s->dbus_path,
-					  WPAS_DBUS_IFACE_INTERFACE,
-					  "Certification");
-	if (_signal == NULL) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: %s: Could not create dbus signal; likely out of memory",
-			   __func__);
-		return;
-	}
-
-	hash = cert_hash ? cert_hash : "";
-	cert_hex = cert ? wpabuf_head(cert) : "";
-	cert_hex_len = cert ? wpabuf_len(cert) : 0;
-
-	if (!dbus_message_append_args(_signal,
-				      DBUS_TYPE_INT32, &depth,
-				      DBUS_TYPE_STRING, &subject,
-				      DBUS_TYPE_STRING, &hash,
-				      DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
-				      &cert_hex, cert_hex_len,
-				      DBUS_TYPE_INVALID)) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: %s: Not enough memory to construct signal",
-			   __func__);
-		goto out;
-	}
-
-	dbus_connection_send(iface->con, _signal, NULL);
-
-out:
-	dbus_message_unref(_signal);
-
-}
-
-
-/**
- * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * Returns: 0 on success, -1 on failure
- *
- * Initialize the dbus control interface and start receiving commands from
- * external programs over the bus.
- */
-int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
-{
-	DBusError error;
-	int ret = -1;
-	DBusObjectPathVTable wpas_vtable = {
-		NULL, &wpas_message_handler, NULL, NULL, NULL, NULL
-	};
-
-	/* Register the message handler for the global dbus interface */
-	if (!dbus_connection_register_object_path(iface->con,
-						  WPAS_DBUS_PATH, &wpas_vtable,
-						  iface)) {
-		wpa_printf(MSG_ERROR, "dbus: Could not set up message handler");
-		return -1;
-	}
-
-	/* Register our service with the message bus */
-	dbus_error_init(&error);
-	switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE,
-				      0, &error)) {
-	case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
-		ret = 0;
-		break;
-	case DBUS_REQUEST_NAME_REPLY_EXISTS:
-	case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
-	case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
-		wpa_printf(MSG_ERROR,
-			   "dbus: Could not request service name: already registered");
-		break;
-	default:
-		wpa_printf(MSG_ERROR,
-			   "dbus: Could not request service name: %s %s",
-			   error.name, error.message);
-		break;
-	}
-	dbus_error_free(&error);
-
-	if (ret != 0)
-		return -1;
-
-	wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE
-		   "'.");
-
-	return 0;
-}
-
-
-/**
- * wpas_dbus_register_new_iface - Register a new interface with dbus
- * @wpa_s: %wpa_supplicant interface description structure to register
- * Returns: 0 on success, -1 on error
- *
- * Registers a new interface with dbus and assigns it a dbus object path.
- */
-int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
-{
-	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
-	DBusConnection * con;
-	u32 next;
-	DBusObjectPathVTable vtable = {
-		NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL
-	};
-
-	/* Do nothing if the control interface is not turned on */
-	if (ctrl_iface == NULL)
-		return 0;
-
-	con = ctrl_iface->con;
-	next = ctrl_iface->next_objid++;
-
-	/* Create and set the interface's object path */
-	wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
-	if (wpa_s->dbus_path == NULL)
-		return -1;
-	os_snprintf(wpa_s->dbus_path, WPAS_DBUS_OBJECT_PATH_MAX,
-		    WPAS_DBUS_PATH_INTERFACES "/%u",
-		    next);
-
-	/* Register the message handler for the interface functions */
-	if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable,
-					       wpa_s)) {
-		wpa_printf(MSG_ERROR,
-			   "dbus: Could not set up message handler for interface %s",
-			   wpa_s->ifname);
-		return -1;
-	}
-
-	return 0;
-}
-
-
-/**
- * wpas_dbus_unregister_iface - Unregister an interface from dbus
- * @wpa_s: wpa_supplicant interface structure
- * Returns: 0 on success, -1 on failure
- *
- * Unregisters the interface with dbus
- */
-int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
-{
-	struct wpas_dbus_priv *ctrl_iface;
-	DBusConnection *con;
-
-	/* 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 || wpa_s->dbus_path == NULL)
-		return 0;
-
-	con = ctrl_iface->con;
-	if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path))
-		return -1;
-
-	os_free(wpa_s->dbus_path);
-	wpa_s->dbus_path = NULL;
-
-	return 0;
-}
-
-
-/**
- * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * @path: Pointer to a dbus object path representing an interface
- * Returns: Pointer to the interface or %NULL if not found
- */
-struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
-	struct wpa_global *global, const char *path)
-{
-	struct wpa_supplicant *wpa_s;
-
-	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
-		if (wpa_s->dbus_path && strcmp(wpa_s->dbus_path, path) == 0)
-			return wpa_s;
-	}
-	return NULL;
-}
diff --git a/wpa_supplicant/dbus/dbus_old.h b/wpa_supplicant/dbus/dbus_old.h
deleted file mode 100644
index 451a9f8..0000000
--- a/wpa_supplicant/dbus/dbus_old.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_DBUS_H
-#define CTRL_IFACE_DBUS_H
-
-struct wps_credential;
-
-#ifdef CONFIG_CTRL_IFACE_DBUS
-
-#define WPAS_DBUS_OBJECT_PATH_MAX 150
-
-#define WPAS_DBUS_SERVICE	"fi.epitest.hostap.WPASupplicant"
-#define WPAS_DBUS_PATH		"/fi/epitest/hostap/WPASupplicant"
-#define WPAS_DBUS_INTERFACE	"fi.epitest.hostap.WPASupplicant"
-
-#define WPAS_DBUS_PATH_INTERFACES	WPAS_DBUS_PATH "/Interfaces"
-#define WPAS_DBUS_IFACE_INTERFACE	WPAS_DBUS_INTERFACE ".Interface"
-
-#define WPAS_DBUS_NETWORKS_PART "Networks"
-#define WPAS_DBUS_IFACE_NETWORK	WPAS_DBUS_INTERFACE ".Network"
-
-#define WPAS_DBUS_BSSIDS_PART	"BSSIDs"
-#define WPAS_DBUS_IFACE_BSSID	WPAS_DBUS_INTERFACE ".BSSID"
-
-
-/* Errors */
-#define WPAS_ERROR_INVALID_NETWORK \
-	WPAS_DBUS_IFACE_INTERFACE ".InvalidNetwork"
-#define WPAS_ERROR_INVALID_BSSID \
-	WPAS_DBUS_IFACE_INTERFACE ".InvalidBSSID"
-
-#define WPAS_ERROR_INVALID_OPTS \
-	WPAS_DBUS_INTERFACE ".InvalidOptions"
-#define WPAS_ERROR_INVALID_IFACE \
-	WPAS_DBUS_INTERFACE ".InvalidInterface"
-
-#define WPAS_ERROR_ADD_ERROR \
-	WPAS_DBUS_INTERFACE ".AddError"
-#define WPAS_ERROR_EXISTS_ERROR \
-	WPAS_DBUS_INTERFACE ".ExistsError"
-#define WPAS_ERROR_REMOVE_ERROR \
-	WPAS_DBUS_INTERFACE ".RemoveError"
-
-#define WPAS_ERROR_SCAN_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".ScanError"
-#define WPAS_ERROR_ADD_NETWORK_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".AddNetworkError"
-#define WPAS_ERROR_INTERNAL_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".InternalError"
-#define WPAS_ERROR_REMOVE_NETWORK_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".RemoveNetworkError"
-
-#define WPAS_ERROR_WPS_PBC_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".WpsPbcError"
-#define WPAS_ERROR_WPS_PIN_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".WpsPinError"
-#define WPAS_ERROR_WPS_REG_ERROR \
-	WPAS_DBUS_IFACE_INTERFACE ".WpsRegError"
-
-#define WPAS_DBUS_BSSID_FORMAT "%02x%02x%02x%02x%02x%02x"
-
-struct wpa_global;
-struct wpa_supplicant;
-
-int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface);
-void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
-					     enum wpa_states new_state,
-					     enum wpa_states old_state);
-void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
-					 const struct wps_credential *cred);
-void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
-					      int depth, const char *subject,
-					      const char *cert_hash,
-					      const struct wpabuf *cert);
-
-char * wpas_dbus_decompose_object_path(const char *path, char **network,
-				       char **bssid);
-
-int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s);
-int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s);
-
-
-/* Methods internal to the dbus control interface */
-struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
-	struct wpa_global *global, const char *path);
-
-#else /* CONFIG_CTRL_IFACE_DBUS */
-
-static inline void
-wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
-					enum wpa_states new_state,
-					enum wpa_states old_state)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
-				    const struct wps_credential *cred)
-{
-}
-
-static inline void
-wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
-					      int depth, const char *subject,
-					      const char *cert_hash,
-					      const struct wpabuf *cert)
-{
-}
-
-static inline int
-wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-
-static inline int
-wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-
-#endif /* CONFIG_CTRL_IFACE_DBUS */
-
-#endif /* CTRL_IFACE_DBUS_H */
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
deleted file mode 100644
index e540832..0000000
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "eap_peer/eap_methods.h"
-#include "common/ieee802_11_defs.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../driver_i.h"
-#include "../notify.h"
-#include "../wpas_glue.h"
-#include "../bss.h"
-#include "../scan.h"
-#include "dbus_old.h"
-#include "dbus_old_handlers.h"
-#include "dbus_dict_helpers.h"
-
-/**
- * wpas_dbus_new_invalid_opts_error - Return a new invalid options error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid options error
- */
-DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
-					       const char *arg)
-{
-	DBusMessage *reply;
-
-	reply = dbus_message_new_error(
-		message, WPAS_ERROR_INVALID_OPTS,
-		"Did not receive correct message arguments.");
-	if (arg != NULL)
-		dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
-					 DBUS_TYPE_INVALID);
-
-	return reply;
-}
-
-
-/**
- * wpas_dbus_new_success_reply - Return a new success reply message
- * @message: Pointer to incoming dbus message this reply refers to
- * Returns: a dbus message containing a single UINT32 that indicates
- *          success (ie, a value of 1)
- *
- * Convenience function to create and return a success reply message
- */
-DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message)
-{
-	DBusMessage *reply;
-	unsigned int success = 1;
-
-	reply = dbus_message_new_method_return(message);
-	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success,
-				 DBUS_TYPE_INVALID);
-	return reply;
-}
-
-
-/**
- * wpas_dbus_global_add_interface - Request registration of a network interface
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object path of the new interface object,
- *          or a dbus error message with more information
- *
- * Handler function for "addInterface" method call. Handles requests
- * by dbus clients to register a network interface that wpa_supplicant
- * will manage.
- */
-DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
-					     struct wpa_global *global)
-{
-	char *ifname = NULL;
-	char *driver = NULL;
-	char *driver_param = NULL;
-	char *confname = NULL;
-	char *bridge_ifname = NULL;
-	DBusMessage *reply = NULL;
-	DBusMessageIter iter;
-
-	dbus_message_iter_init(message, &iter);
-
-	/* First argument: interface name (DBUS_TYPE_STRING)
-	 *    Required; must be non-zero length
-	 */
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
-		goto error;
-	dbus_message_iter_get_basic(&iter, &ifname);
-	if (!os_strlen(ifname))
-		goto error;
-
-	/* Second argument: dict of options */
-	if (dbus_message_iter_next(&iter)) {
-		DBusMessageIter iter_dict;
-		struct wpa_dbus_dict_entry entry;
-
-		if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
-			goto error;
-		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
-			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
-				goto error;
-			if (!strcmp(entry.key, "driver") &&
-			    entry.type == DBUS_TYPE_STRING) {
-				os_free(driver);
-				driver = os_strdup(entry.str_value);
-				wpa_dbus_dict_entry_clear(&entry);
-				if (driver == NULL)
-					goto error;
-			} else if (!strcmp(entry.key, "driver-params") &&
-				   entry.type == DBUS_TYPE_STRING) {
-				os_free(driver_param);
-				driver_param = os_strdup(entry.str_value);
-				wpa_dbus_dict_entry_clear(&entry);
-				if (driver_param == NULL)
-					goto error;
-			} else if (!strcmp(entry.key, "config-file") &&
-				   entry.type == DBUS_TYPE_STRING) {
-				os_free(confname);
-				confname = os_strdup(entry.str_value);
-				wpa_dbus_dict_entry_clear(&entry);
-				if (confname == NULL)
-					goto error;
-			} else if (!strcmp(entry.key, "bridge-ifname") &&
-				   entry.type == DBUS_TYPE_STRING) {
-				os_free(bridge_ifname);
-				bridge_ifname = os_strdup(entry.str_value);
-				wpa_dbus_dict_entry_clear(&entry);
-				if (bridge_ifname == NULL)
-					goto error;
-			} else {
-				wpa_dbus_dict_entry_clear(&entry);
-				goto error;
-			}
-		}
-	}
-
-	/*
-	 * Try to get the wpa_supplicant record for this iface, return
-	 * an error if we already control it.
-	 */
-	if (wpa_supplicant_get_iface(global, ifname) != NULL) {
-		reply = dbus_message_new_error(
-			message, WPAS_ERROR_EXISTS_ERROR,
-			"wpa_supplicant already controls this interface.");
-	} else {
-		struct wpa_supplicant *wpa_s;
-		struct wpa_interface iface;
-
-		os_memset(&iface, 0, sizeof(iface));
-		iface.ifname = ifname;
-		iface.driver = driver;
-		iface.driver_param = driver_param;
-		iface.confname = confname;
-		iface.bridge_ifname = bridge_ifname;
-		/* Otherwise, have wpa_supplicant attach to it. */
-		wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
-		if (wpa_s && wpa_s->dbus_path) {
-			const char *path = wpa_s->dbus_path;
-
-			reply = dbus_message_new_method_return(message);
-			dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
-						 &path, DBUS_TYPE_INVALID);
-		} else {
-			reply = dbus_message_new_error(
-				message, WPAS_ERROR_ADD_ERROR,
-				"wpa_supplicant couldn't grab this interface.");
-		}
-	}
-
-out:
-	os_free(driver);
-	os_free(driver_param);
-	os_free(confname);
-	os_free(bridge_ifname);
-	return reply;
-
-error:
-	reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-	goto out;
-}
-
-
-/**
- * wpas_dbus_global_remove_interface - Request deregistration of an interface
- * @message: Pointer to incoming dbus message
- * @global: wpa_supplicant global data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- *          failure (0), or returns a dbus error message with more information
- *
- * Handler function for "removeInterface" method call.  Handles requests
- * by dbus clients to deregister a network interface that wpa_supplicant
- * currently manages.
- */
-DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
-						struct wpa_global *global)
-{
-	struct wpa_supplicant *wpa_s;
-	char *path;
-	DBusMessage *reply = NULL;
-
-	if (!dbus_message_get_args(message, NULL,
-				   DBUS_TYPE_OBJECT_PATH, &path,
-				   DBUS_TYPE_INVALID)) {
-		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-		goto out;
-	}
-
-	wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path);
-	if (wpa_s == NULL) {
-		reply = wpas_dbus_new_invalid_iface_error(message);
-		goto out;
-	}
-
-	if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) {
-		reply = wpas_dbus_new_success_reply(message);
-	} else {
-		reply = dbus_message_new_error(
-			message, WPAS_ERROR_REMOVE_ERROR,
-			"wpa_supplicant couldn't remove this interface.");
-	}
-
-out:
-	return reply;
-}
-
-
-/**
- * wpas_dbus_global_get_interface - Get the object path for an interface name
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object path of the interface object,
- *          or a dbus error message with more information
- *
- * Handler function for "getInterface" method call. Handles requests
- * by dbus clients for the object path of an specific network interface.
- */
-DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
-					     struct wpa_global *global)
-{
-	DBusMessage *reply = NULL;
-	const char *ifname;
-	const char *path;
-	struct wpa_supplicant *wpa_s;
-
-	if (!dbus_message_get_args(message, NULL,
-				   DBUS_TYPE_STRING, &ifname,
-				   DBUS_TYPE_INVALID)) {
-		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-		goto out;
-	}
-
-	wpa_s = wpa_supplicant_get_iface(global, ifname);
-	if (wpa_s == NULL || !wpa_s->dbus_path) {
-		reply = wpas_dbus_new_invalid_iface_error(message);
-		goto out;
-	}
-
-	path = wpa_s->dbus_path;
-	reply = dbus_message_new_method_return(message);
-	dbus_message_append_args(reply,
-				 DBUS_TYPE_OBJECT_PATH, &path,
-				 DBUS_TYPE_INVALID);
-
-out:
-	return reply;
-}
-
-
-/**
- * wpas_dbus_global_set_debugparams- Set the debug params
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- *          failure (0), or returns a dbus error message with more information
- *
- * Handler function for "setDebugParams" method call. Handles requests
- * by dbus clients for the object path of an specific network interface.
- */
-DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
-					       struct wpa_global *global)
-{
-	DBusMessage *reply = NULL;
-	int debug_level;
-	dbus_bool_t debug_timestamp;
-	dbus_bool_t debug_show_keys;
-
-	if (!dbus_message_get_args(message, NULL,
-				   DBUS_TYPE_INT32, &debug_level,
-				   DBUS_TYPE_BOOLEAN, &debug_timestamp,
-				   DBUS_TYPE_BOOLEAN, &debug_show_keys,
-				   DBUS_TYPE_INVALID)) {
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-	}
-
-	if (wpa_supplicant_set_debug_params(global, debug_level,
-					    debug_timestamp ? 1 : 0,
-					    debug_show_keys ? 1 : 0)) {
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-	}
-
-	reply = wpas_dbus_new_success_reply(message);
-
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_scan - Request a wireless scan on an interface
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "scan" method call of a network device. Requests
- * that wpa_supplicant perform a wireless scan as soon as possible
- * on a particular wireless interface.
- */
-DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
-				   struct wpa_supplicant *wpa_s)
-{
-	wpa_s->scan_req = MANUAL_SCAN_REQ;
-	wpa_supplicant_req_scan(wpa_s, 0, 0);
-	return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_scan_results - Get the results of a recent scan request
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing a dbus array of objects paths, or returns
- *          a dbus error message if not scan results could be found
- *
- * Handler function for "scanResults" method call of a network device. Returns
- * a dbus message containing the object paths of wireless networks found.
- */
-DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply;
-	DBusMessageIter iter;
-	DBusMessageIter sub_iter;
-	struct wpa_bss *bss;
-
-	if (!wpa_s->dbus_path)
-		return dbus_message_new_error(message,
-					      WPAS_ERROR_INTERNAL_ERROR,
-					      "no D-Bus interface available");
-
-	/* Create and initialize the return message */
-	reply = dbus_message_new_method_return(message);
-	dbus_message_iter_init_append(reply, &iter);
-	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-					      DBUS_TYPE_OBJECT_PATH_AS_STRING,
-					      &sub_iter))
-		goto error;
-
-	/* Loop through scan results and append each result's object path */
-	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
-		char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
-		char *path = path_buf;
-
-		/* Construct the object path for this network.  Note that ':'
-		 * is not a valid character in dbus object paths.
-		 */
-		os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
-			    "%s/" WPAS_DBUS_BSSIDS_PART "/"
-			    WPAS_DBUS_BSSID_FORMAT,
-			    wpa_s->dbus_path, MAC2STR(bss->bssid));
-		if (!dbus_message_iter_append_basic(&sub_iter,
-						    DBUS_TYPE_OBJECT_PATH,
-						    &path))
-			goto error;
-	}
-
-	if (!dbus_message_iter_close_container(&iter, &sub_iter))
-		goto error;
-
-	return reply;
-
-error:
-	dbus_message_unref(reply);
-	return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
-				      "an internal error occurred returning scan results");
-}
-
-
-/**
- * wpas_dbus_bssid_properties - Return the properties of a scanned network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @res: wpa_supplicant scan result for which to get properties
- * Returns: a dbus message containing the properties for the requested network
- *
- * Handler function for "properties" method call of a scanned network.
- * Returns a dbus message containing the the properties.
- */
-DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
-					 struct wpa_supplicant *wpa_s,
-					 struct wpa_bss *bss)
-{
-	DBusMessage *reply;
-	DBusMessageIter iter, iter_dict;
-	const u8 *wpa_ie, *rsn_ie, *wps_ie;
-
-	/* Dump the properties into a dbus message */
-	reply = dbus_message_new_method_return(message);
-
-	wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
-	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
-	wps_ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
-
-	dbus_message_iter_init_append(reply, &iter);
-	if (!wpa_dbus_dict_open_write(&iter, &iter_dict) ||
-	    !wpa_dbus_dict_append_byte_array(&iter_dict, "bssid",
-					     (const char *) bss->bssid,
-					     ETH_ALEN) ||
-	    !wpa_dbus_dict_append_byte_array(&iter_dict, "ssid",
-					     (const char *) bss->ssid,
-					     bss->ssid_len) ||
-	    (wpa_ie &&
-	     !wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie",
-					      (const char *) wpa_ie,
-					      wpa_ie[1] + 2)) ||
-	    (rsn_ie &&
-	     !wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie",
-					      (const char *) rsn_ie,
-					      rsn_ie[1] + 2)) ||
-	    (wps_ie &&
-	     !wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie",
-					     (const char *) wps_ie,
-					      wps_ie[1] + 2)) ||
-	    (bss->freq &&
-	     !wpa_dbus_dict_append_int32(&iter_dict, "frequency", bss->freq)) ||
-	    !wpa_dbus_dict_append_uint16(&iter_dict, "capabilities",
-					 bss->caps) ||
-	    (!(bss->flags & WPA_BSS_QUAL_INVALID) &&
-	     !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual)) ||
-	    (!(bss->flags & WPA_BSS_NOISE_INVALID) &&
-	     !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise)) ||
-	    (!(bss->flags & WPA_BSS_LEVEL_INVALID) &&
-	     !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level)) ||
-	    !wpa_dbus_dict_append_int32(&iter_dict, "maxrate",
-					wpa_bss_get_max_rate(bss) * 500000) ||
-	    !wpa_dbus_dict_close_write(&iter, &iter_dict)) {
-		if (reply)
-			dbus_message_unref(reply);
-		reply = dbus_message_new_error(
-			message, WPAS_ERROR_INTERNAL_ERROR,
-			"an internal error occurred returning BSSID properties.");
-	}
-
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_capabilities - Return interface capabilities
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a dict of strings
- *
- * Handler function for "capabilities" method call of an interface.
- */
-DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	struct wpa_driver_capa capa;
-	int res;
-	DBusMessageIter iter, iter_dict;
-	char **eap_methods;
-	size_t num_items;
-	dbus_bool_t strict = FALSE;
-	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
-
-	if (!dbus_message_get_args(message, NULL,
-				   DBUS_TYPE_BOOLEAN, &strict,
-				   DBUS_TYPE_INVALID))
-		strict = FALSE;
-
-	reply = dbus_message_new_method_return(message);
-
-	dbus_message_iter_init_append(reply, &iter);
-	if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
-		goto error;
-
-	/* EAP methods */
-	eap_methods = eap_get_names_as_string_array(&num_items);
-	if (eap_methods) {
-		dbus_bool_t success;
-		size_t i = 0;
-
-		success = wpa_dbus_dict_append_string_array(
-			&iter_dict, "eap", (const char **) eap_methods,
-			num_items);
-
-		/* free returned method array */
-		while (eap_methods[i])
-			os_free(eap_methods[i++]);
-		os_free(eap_methods);
-
-		if (!success)
-			goto error;
-	}
-
-	res = wpa_drv_get_capa(wpa_s, &capa);
-
-	/***** pairwise cipher */
-	if (res < 0) {
-		if (!strict) {
-			const char *args[] = {"CCMP", "TKIP", "NONE"};
-
-			if (!wpa_dbus_dict_append_string_array(
-				    &iter_dict, "pairwise", args,
-				    ARRAY_SIZE(args)))
-				goto error;
-		}
-	} else {
-		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise",
-						      &iter_dict_entry,
-						      &iter_dict_val,
-						      &iter_array) ||
-		    ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "CCMP")) ||
-		    ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "TKIP")) ||
-		    ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "NONE")) ||
-		    !wpa_dbus_dict_end_string_array(&iter_dict,
-						    &iter_dict_entry,
-						    &iter_dict_val,
-						    &iter_array))
-			goto error;
-	}
-
-	/***** group cipher */
-	if (res < 0) {
-		if (!strict) {
-			const char *args[] = {
-				"CCMP", "TKIP", "WEP104", "WEP40"
-			};
-
-			if (!wpa_dbus_dict_append_string_array(
-				    &iter_dict, "group", args,
-				    ARRAY_SIZE(args)))
-				goto error;
-		}
-	} else {
-		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group",
-						      &iter_dict_entry,
-						      &iter_dict_val,
-						      &iter_array))
-			goto error;
-
-		if (((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "CCMP")) ||
-		    ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "TKIP")) ||
-		    ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "WEP104")) ||
-		    ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "WEP40")) ||
-		    !wpa_dbus_dict_end_string_array(&iter_dict,
-						    &iter_dict_entry,
-						    &iter_dict_val,
-						    &iter_array))
-			goto error;
-	}
-
-	/***** key management */
-	if (res < 0) {
-		if (!strict) {
-			const char *args[] = {
-				"WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE",
-				"NONE"
-			};
-			if (!wpa_dbus_dict_append_string_array(
-				    &iter_dict, "key_mgmt", args,
-				    ARRAY_SIZE(args)))
-				goto error;
-		}
-	} else {
-		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt",
-						      &iter_dict_entry,
-						      &iter_dict_val,
-						      &iter_array) ||
-		    !wpa_dbus_dict_string_array_add_element(&iter_array,
-							    "NONE") ||
-		    !wpa_dbus_dict_string_array_add_element(&iter_array,
-							    "IEEE8021X") ||
-		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
-				       WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "WPA-EAP")) ||
-		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
-				       WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "WPA-PSK")) ||
-		    ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "WPA-NONE")) ||
-		    !wpa_dbus_dict_end_string_array(&iter_dict,
-						    &iter_dict_entry,
-						    &iter_dict_val,
-						    &iter_array))
-			goto error;
-	}
-
-	/***** WPA protocol */
-	if (res < 0) {
-		if (!strict) {
-			const char *args[] = { "RSN", "WPA" };
-
-			if (!wpa_dbus_dict_append_string_array(
-				    &iter_dict, "proto", args,
-				    ARRAY_SIZE(args)))
-				goto error;
-		}
-	} else {
-		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto",
-						      &iter_dict_entry,
-						      &iter_dict_val,
-						      &iter_array) ||
-		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
-				       WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "RSN")) ||
-		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
-				       WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "WPA")) ||
-		    !wpa_dbus_dict_end_string_array(&iter_dict,
-						    &iter_dict_entry,
-						    &iter_dict_val,
-						    &iter_array))
-			goto error;
-	}
-
-	/***** auth alg */
-	if (res < 0) {
-		if (!strict) {
-			const char *args[] = { "OPEN", "SHARED", "LEAP" };
-
-			if (!wpa_dbus_dict_append_string_array(
-				    &iter_dict, "auth_alg", args,
-				    ARRAY_SIZE(args)))
-				goto error;
-		}
-	} else {
-		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg",
-						      &iter_dict_entry,
-						      &iter_dict_val,
-						      &iter_array) ||
-		    ((capa.auth & WPA_DRIVER_AUTH_OPEN) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "OPEN")) ||
-		    ((capa.auth & WPA_DRIVER_AUTH_SHARED) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "SHARED")) ||
-		    ((capa.auth & WPA_DRIVER_AUTH_LEAP) &&
-		     !wpa_dbus_dict_string_array_add_element(
-			     &iter_array, "LEAP")) ||
-		    !wpa_dbus_dict_end_string_array(&iter_dict,
-						    &iter_dict_entry,
-						    &iter_dict_val,
-						    &iter_array))
-			goto error;
-	}
-
-	if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
-		goto error;
-
-	return reply;
-
-error:
-	if (reply)
-		dbus_message_unref(reply);
-	return dbus_message_new_error(
-		message, WPAS_ERROR_INTERNAL_ERROR,
-		"an internal error occurred returning interface capabilities.");
-}
-
-
-/**
- * wpas_dbus_iface_add_network - Add a new configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing the object path of the new network
- *
- * Handler function for "addNetwork" method call of a network interface.
- */
-DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
-					  struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	struct wpa_ssid *ssid = NULL;
-	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
-
-	if (wpa_s->dbus_path)
-		ssid = wpa_supplicant_add_network(wpa_s);
-	if (ssid == NULL) {
-		reply = dbus_message_new_error(
-			message, WPAS_ERROR_ADD_NETWORK_ERROR,
-			"wpa_supplicant could not add a network on this interface.");
-		goto out;
-	}
-
-	/* Construct the object path for this network. */
-	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
-		    "%s/" WPAS_DBUS_NETWORKS_PART "/%d",
-		    wpa_s->dbus_path, ssid->id);
-
-	reply = dbus_message_new_method_return(message);
-	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
-				 &path, DBUS_TYPE_INVALID);
-
-out:
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_remove_network - Remove a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "removeNetwork" method call of a network interface.
- */
-DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	const char *op;
-	char *iface = NULL, *net_id = NULL;
-	int id;
-	int result;
-
-	if (!dbus_message_get_args(message, NULL,
-				   DBUS_TYPE_OBJECT_PATH, &op,
-				   DBUS_TYPE_INVALID)) {
-		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-		goto out;
-	}
-
-	/* Extract the network ID */
-	iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
-	if (iface == NULL || net_id == NULL) {
-		reply = wpas_dbus_new_invalid_network_error(message);
-		goto out;
-	}
-
-	/* Ensure the network is actually a child of this interface */
-	if (!wpa_s->dbus_path || os_strcmp(iface, wpa_s->dbus_path) != 0) {
-		reply = wpas_dbus_new_invalid_network_error(message);
-		goto out;
-	}
-
-	id = strtoul(net_id, NULL, 10);
-	result = wpa_supplicant_remove_network(wpa_s, id);
-	if (result == -1) {
-		reply = wpas_dbus_new_invalid_network_error(message);
-		goto out;
-	}
-	if (result == -2) {
-		reply = dbus_message_new_error(
-			message, WPAS_ERROR_REMOVE_NETWORK_ERROR,
-			"error removing the specified on this interface.");
-		goto out;
-	}
-
-	reply = wpas_dbus_new_success_reply(message);
-
-out:
-	os_free(iface);
-	os_free(net_id);
-	return reply;
-}
-
-
-static const char * const dont_quote[] = {
-	"key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
-	"opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
-	"bssid", "scan_freq", "freq_list", NULL
-};
-
-
-static dbus_bool_t should_quote_opt(const char *key)
-{
-	int i = 0;
-
-	while (dont_quote[i] != NULL) {
-		if (os_strcmp(key, dont_quote[i]) == 0)
-			return FALSE;
-		i++;
-	}
-	return TRUE;
-}
-
-
-/**
- * wpas_dbus_iface_set_network - Set options for a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "set" method call of a configured network.
- */
-DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
-					  struct wpa_supplicant *wpa_s,
-					  struct wpa_ssid *ssid)
-{
-	DBusMessage *reply = NULL;
-	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
-	DBusMessageIter	iter, iter_dict;
-
-	dbus_message_iter_init(message, &iter);
-
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
-		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-		goto out;
-	}
-
-	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
-		char *value = NULL;
-		size_t size = 50;
-		int ret;
-
-		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
-			reply = wpas_dbus_new_invalid_opts_error(message,
-								 NULL);
-			goto out;
-		}
-
-		/* Type conversions, since wpa_supplicant wants strings */
-		if (entry.type == DBUS_TYPE_ARRAY &&
-		    entry.array_type == DBUS_TYPE_BYTE) {
-			if (entry.array_len <= 0)
-				goto error;
-
-			size = entry.array_len * 2 + 1;
-			value = os_zalloc(size);
-			if (value == NULL)
-				goto error;
-			ret = wpa_snprintf_hex(value, size,
-					       (u8 *) entry.bytearray_value,
-					       entry.array_len);
-			if (ret <= 0)
-				goto error;
-		} else if (entry.type == DBUS_TYPE_STRING) {
-			if (should_quote_opt(entry.key)) {
-				size = os_strlen(entry.str_value);
-				/* Zero-length option check */
-				if (size == 0)
-					goto error;
-				size += 3;  /* For quotes and terminator */
-				value = os_zalloc(size);
-				if (value == NULL)
-					goto error;
-				ret = os_snprintf(value, size, "\"%s\"",
-						  entry.str_value);
-				if (os_snprintf_error(size, ret))
-					goto error;
-			} else {
-				value = os_strdup(entry.str_value);
-				if (value == NULL)
-					goto error;
-			}
-		} else if (entry.type == DBUS_TYPE_UINT32) {
-			value = os_zalloc(size);
-			if (value == NULL)
-				goto error;
-			ret = os_snprintf(value, size, "%u",
-					  entry.uint32_value);
-			if (os_snprintf_error(size, ret))
-				goto error;
-		} else if (entry.type == DBUS_TYPE_INT32) {
-			value = os_zalloc(size);
-			if (value == NULL)
-				goto error;
-			ret = os_snprintf(value, size, "%d",
-					  entry.int32_value);
-			if (os_snprintf_error(size, ret))
-				goto error;
-		} else
-			goto error;
-
-		if (wpa_config_set(ssid, entry.key, value, 0) < 0)
-			goto error;
-
-		if ((os_strcmp(entry.key, "psk") == 0 &&
-		     value[0] == '"' && ssid->ssid_len) ||
-		    (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
-			wpa_config_update_psk(ssid);
-		else if (os_strcmp(entry.key, "priority") == 0)
-			wpa_config_update_prio_list(wpa_s->conf);
-
-		os_free(value);
-		wpa_dbus_dict_entry_clear(&entry);
-		continue;
-
-	error:
-		os_free(value);
-		reply = wpas_dbus_new_invalid_opts_error(message, entry.key);
-		wpa_dbus_dict_entry_clear(&entry);
-		break;
-	}
-
-	if (!reply)
-		reply = wpas_dbus_new_success_reply(message);
-
-out:
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_enable_network - Mark a configured network as enabled
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "enable" method call of a configured network.
- */
-DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s,
-					     struct wpa_ssid *ssid)
-{
-	wpa_supplicant_enable_network(wpa_s, ssid);
-	return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_disable_network - Mark a configured network as disabled
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "disable" method call of a configured network.
- */
-DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
-					      struct wpa_supplicant *wpa_s,
-					      struct wpa_ssid *ssid)
-{
-	wpa_supplicant_disable_network(wpa_s, ssid);
-	return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_select_network - Attempt association with a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "selectNetwork" method call of network interface.
- */
-DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	const char *op;
-	struct wpa_ssid *ssid;
-	char *iface_obj_path = NULL;
-	char *network = NULL;
-
-	if (os_strlen(dbus_message_get_signature(message)) == 0) {
-		/* Any network */
-		ssid = NULL;
-	} else {
-		int nid;
-
-		if (!dbus_message_get_args(message, NULL,
-					   DBUS_TYPE_OBJECT_PATH, &op,
-					   DBUS_TYPE_INVALID)) {
-			reply = wpas_dbus_new_invalid_opts_error(message,
-								 NULL);
-			goto out;
-		}
-
-		/* Extract the network number */
-		iface_obj_path = wpas_dbus_decompose_object_path(op,
-								 &network,
-								 NULL);
-		if (iface_obj_path == NULL) {
-			reply = wpas_dbus_new_invalid_iface_error(message);
-			goto out;
-		}
-		/* Ensure the object path really points to this interface */
-		if (network == NULL || !wpa_s->dbus_path ||
-		    os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
-			reply = wpas_dbus_new_invalid_network_error(message);
-			goto out;
-		}
-
-		nid = strtoul(network, NULL, 10);
-		if (errno == EINVAL) {
-			reply = wpas_dbus_new_invalid_network_error(message);
-			goto out;
-		}
-
-		ssid = wpa_config_get_network(wpa_s->conf, nid);
-		if (ssid == NULL) {
-			reply = wpas_dbus_new_invalid_network_error(message);
-			goto out;
-		}
-	}
-
-	/* Finally, associate with the network */
-	wpa_supplicant_select_network(wpa_s, ssid);
-
-	reply = wpas_dbus_new_success_reply(message);
-
-out:
-	os_free(iface_obj_path);
-	os_free(network);
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_disconnect - Terminate the current connection
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "disconnect" method call of network interface.
- */
-DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
-					 struct wpa_supplicant *wpa_s)
-{
-	wpas_request_disconnection(wpa_s);
-
-	return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_set_ap_scan - Control roaming mode
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "setAPScan" method call.
- */
-DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
-					  struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	dbus_uint32_t ap_scan = 1;
-
-	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan,
-				   DBUS_TYPE_INVALID)) {
-		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-		goto out;
-	}
-
-	if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
-		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
-		goto out;
-	}
-
-	reply = wpas_dbus_new_success_reply(message);
-
-out:
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "setSmartcardModules" method call.
- */
-DBusMessage * wpas_dbus_iface_set_smartcard_modules(
-	DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
-	DBusMessageIter iter, iter_dict;
-	char *opensc_engine_path = NULL;
-	char *pkcs11_engine_path = NULL;
-	char *pkcs11_module_path = NULL;
-	struct wpa_dbus_dict_entry entry;
-
-	if (!dbus_message_iter_init(message, &iter))
-		goto error;
-
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
-		goto error;
-
-	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
-		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
-			goto error;
-		if (!strcmp(entry.key, "opensc_engine_path") &&
-		    entry.type == DBUS_TYPE_STRING) {
-			os_free(opensc_engine_path);
-			opensc_engine_path = os_strdup(entry.str_value);
-			wpa_dbus_dict_entry_clear(&entry);
-			if (opensc_engine_path == NULL)
-				goto error;
-		} else if (!strcmp(entry.key, "pkcs11_engine_path") &&
-			   entry.type == DBUS_TYPE_STRING) {
-			os_free(pkcs11_engine_path);
-			pkcs11_engine_path = os_strdup(entry.str_value);
-			wpa_dbus_dict_entry_clear(&entry);
-			if (pkcs11_engine_path == NULL)
-				goto error;
-		} else if (!strcmp(entry.key, "pkcs11_module_path") &&
-				 entry.type == DBUS_TYPE_STRING) {
-			os_free(pkcs11_module_path);
-			pkcs11_module_path = os_strdup(entry.str_value);
-			wpa_dbus_dict_entry_clear(&entry);
-			if (pkcs11_module_path == NULL)
-				goto error;
-		} else {
-			wpa_dbus_dict_entry_clear(&entry);
-			goto error;
-		}
-	}
-
-	os_free(wpa_s->conf->opensc_engine_path);
-	wpa_s->conf->opensc_engine_path = opensc_engine_path;
-	os_free(wpa_s->conf->pkcs11_engine_path);
-	wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path;
-	os_free(wpa_s->conf->pkcs11_module_path);
-	wpa_s->conf->pkcs11_module_path = pkcs11_module_path;
-
-	wpa_sm_set_eapol(wpa_s->wpa, NULL);
-	eapol_sm_deinit(wpa_s->eapol);
-	wpa_s->eapol = NULL;
-	wpa_supplicant_init_eapol(wpa_s);
-	wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
-
-	return wpas_dbus_new_success_reply(message);
-
-error:
-	os_free(opensc_engine_path);
-	os_free(pkcs11_engine_path);
-	os_free(pkcs11_module_path);
-	return wpas_dbus_new_invalid_opts_error(message, NULL);
-}
-
-
-/**
- * wpas_dbus_iface_get_state - Get interface state
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a STRING representing the current
- *          interface state
- *
- * Handler function for "state" method call.
- */
-DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
-					struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	const char *str_state;
-
-	reply = dbus_message_new_method_return(message);
-	if (reply != NULL) {
-		str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
-		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state,
-					 DBUS_TYPE_INVALID);
-	}
-
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_get_scanning - Get interface scanning state
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing whether the interface is scanning
- *
- * Handler function for "scanning" method call.
- */
-DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-
-	reply = dbus_message_new_method_return(message);
-	if (reply != NULL) {
-		dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning,
-					 DBUS_TYPE_INVALID);
-	} else {
-		wpa_printf(MSG_ERROR,
-			   "dbus: Not enough memory to return scanning state");
-	}
-
-	return reply;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-
-/**
- * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Asks wpa_supplicant to internally store a one or more binary blobs.
- */
-DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
-					struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
-	DBusMessageIter	iter, iter_dict;
-
-	dbus_message_iter_init(message, &iter);
-
-	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-
-	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
-		struct wpa_config_blob *blob;
-
-		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
-			reply = wpas_dbus_new_invalid_opts_error(message,
-								 NULL);
-			break;
-		}
-
-		if (entry.type != DBUS_TYPE_ARRAY ||
-		    entry.array_type != DBUS_TYPE_BYTE) {
-			reply = wpas_dbus_new_invalid_opts_error(
-				message, "Byte array expected.");
-			break;
-		}
-
-		if ((entry.array_len <= 0) || (entry.array_len > 65536) ||
-		    !strlen(entry.key)) {
-			reply = wpas_dbus_new_invalid_opts_error(
-				message, "Invalid array size.");
-			break;
-		}
-
-		blob = os_zalloc(sizeof(*blob));
-		if (blob == NULL) {
-			reply = dbus_message_new_error(
-				message, WPAS_ERROR_ADD_ERROR,
-				"Not enough memory to add blob.");
-			break;
-		}
-		blob->data = os_zalloc(entry.array_len);
-		if (blob->data == NULL) {
-			reply = dbus_message_new_error(
-				message, WPAS_ERROR_ADD_ERROR,
-				"Not enough memory to add blob data.");
-			os_free(blob);
-			break;
-		}
-
-		blob->name = os_strdup(entry.key);
-		blob->len = entry.array_len;
-		os_memcpy(blob->data, (u8 *) entry.bytearray_value,
-				entry.array_len);
-		if (blob->name == NULL) {
-			wpa_config_free_blob(blob);
-			reply = dbus_message_new_error(
-				message, WPAS_ERROR_ADD_ERROR,
-				"Error adding blob.");
-			break;
-		}
-
-		/* Success */
-		if (!wpa_config_remove_blob(wpa_s->conf, blob->name))
-			wpas_notify_blob_removed(wpa_s, blob->name);
-		wpa_config_set_blob(wpa_s->conf, blob);
-		wpas_notify_blob_added(wpa_s, blob->name);
-
-		wpa_dbus_dict_entry_clear(&entry);
-	}
-	wpa_dbus_dict_entry_clear(&entry);
-
-	return reply ? reply : wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_remove_blob - Remove named binary blobs
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Asks wpa_supplicant to remove one or more previously stored binary blobs.
- */
-DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s)
-{
-	DBusMessageIter iter, array;
-	char *err_msg = NULL;
-
-	dbus_message_iter_init(message, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
-	    dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING)
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-
-	dbus_message_iter_recurse(&iter, &array);
-	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
-		const char *name;
-
-		dbus_message_iter_get_basic(&array, &name);
-		if (!os_strlen(name))
-			err_msg = "Invalid blob name.";
-		else if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
-			err_msg = "Error removing blob.";
-		else
-			wpas_notify_blob_removed(wpa_s, name);
-		dbus_message_iter_next(&array);
-	}
-
-	if (err_msg)
-		return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
-					      err_msg);
-
-	return wpas_dbus_new_success_reply(message);
-}
-
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-/**
- * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- *          failure (0), or returns a dbus error message with more information
- *
- * Handler function for "flush" method call. Handles requests for an
- * interface with an optional "age" parameter that specifies the minimum
- * age of a BSS to be flushed.
- */
-DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
-				    struct wpa_supplicant *wpa_s)
-{
-	int flush_age = 0;
-
-	if (os_strlen(dbus_message_get_signature(message)) != 0 &&
-	    !dbus_message_get_args(message, NULL,
-				   DBUS_TYPE_INT32, &flush_age,
-				   DBUS_TYPE_INVALID)) {
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-	}
-
-	if (flush_age == 0)
-		wpa_bss_flush(wpa_s);
-	else
-		wpa_bss_flush_by_age(wpa_s, flush_age);
-
-	return wpas_dbus_new_success_reply(message);
-}
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.h b/wpa_supplicant/dbus/dbus_old_handlers.h
deleted file mode 100644
index e60ad06..0000000
--- a/wpa_supplicant/dbus/dbus_old_handlers.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_DBUS_HANDLERS_H
-#define CTRL_IFACE_DBUS_HANDLERS_H
-
-struct wpa_bss;
-
-DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message);
-DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message);
-
-DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
-					     struct wpa_global *global);
-
-DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
-						struct wpa_global *global);
-
-DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
-					     struct wpa_global *global);
-
-DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
-					       struct wpa_global *global);
-
-DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
-				   struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
-					 struct wpa_supplicant *wpa_s,
-					 struct wpa_bss *bss);
-
-DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
-					  struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
-					  struct wpa_supplicant *wpa_s,
-					  struct wpa_ssid *ssid);
-
-DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s,
-					     struct wpa_ssid *ssid);
-
-DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
-					      struct wpa_supplicant *wpa_s,
-					      struct wpa_ssid *ssid);
-
-DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
-					     struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
-					 struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
-					  struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_smartcard_modules(
-	DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
-					struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
-					struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
-					   struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
-				    struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message);
-DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
-					       const char *arg);
-
-#endif /* CTRL_IFACE_DBUS_HANDLERS_H */
-
diff --git a/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
deleted file mode 100644
index 987e12d..0000000
--- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface (WPS)
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../wps_supplicant.h"
-#include "dbus_old.h"
-#include "dbus_old_handlers.h"
-
-/**
- * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "wpsPbc" method call
- */
-DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s)
-{
-	char *arg_bssid = NULL;
-	u8 bssid[ETH_ALEN];
-	int ret = 0;
-
-	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
-				   DBUS_TYPE_INVALID))
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-
-	if (os_strcmp(arg_bssid, "any") == 0)
-		ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
-	else if (!hwaddr_aton(arg_bssid, bssid))
-		ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
-	else {
-		return wpas_dbus_new_invalid_opts_error(message,
-							"Invalid BSSID");
-	}
-
-	if (ret < 0) {
-		return dbus_message_new_error(
-			message, WPAS_ERROR_WPS_PBC_ERROR,
-			"Could not start PBC negotiation");
-	}
-
-	return wpas_dbus_new_success_reply(message);
-}
-
-
-/**
- * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "wpsPin" method call
- */
-DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s)
-{
-	DBusMessage *reply = NULL;
-	char *arg_bssid;
-	char *pin = NULL;
-	u8 bssid[ETH_ALEN], *_bssid = NULL;
-	int ret;
-	char npin[9];
-
-	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
-				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-
-	if (os_strcmp(arg_bssid, "any") == 0)
-		_bssid = NULL;
-	else if (!hwaddr_aton(arg_bssid, bssid))
-		_bssid = bssid;
-	else {
-		return wpas_dbus_new_invalid_opts_error(message,
-							"Invalid BSSID");
-	}
-
-	if (os_strlen(pin) > 0)
-		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
-					 DEV_PW_DEFAULT);
-	else
-		ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0,
-					 DEV_PW_DEFAULT);
-
-	if (ret < 0) {
-		return dbus_message_new_error(message,
-					      WPAS_ERROR_WPS_PIN_ERROR,
-					      "Could not init PIN");
-	}
-
-	reply = dbus_message_new_method_return(message);
-	if (reply == NULL)
-		return NULL;
-
-	if (ret > 0) {
-		ret = os_snprintf(npin, sizeof(npin), "%08d", ret);
-		if (os_snprintf_error(sizeof(npin), ret))
-			return wpas_dbus_new_invalid_opts_error(message,
-								"invalid PIN");
-
-		pin = npin;
-	}
-	dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
-				 DBUS_TYPE_INVALID);
-	return reply;
-}
-
-
-/**
- * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing a UINT32 indicating success (1) or
- *          failure (0)
- *
- * Handler function for "wpsReg" method call
- */
-DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
-				      struct wpa_supplicant *wpa_s)
-{
-	char *arg_bssid;
-	char *pin = NULL;
-	u8 bssid[ETH_ALEN];
-	int ret = 0;
-
-	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
-				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
-		return wpas_dbus_new_invalid_opts_error(message, NULL);
-
-	if (!hwaddr_aton(arg_bssid, bssid))
-		ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
-	else {
-		return wpas_dbus_new_invalid_opts_error(message,
-							"Invalid BSSID");
-	}
-
-	if (ret < 0) {
-		return dbus_message_new_error(message,
-					      WPAS_ERROR_WPS_REG_ERROR,
-					      "Could not request credentials");
-	}
-
-	return wpas_dbus_new_success_reply(message);
-}
diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in
deleted file mode 100644
index a75918f..0000000
--- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in
+++ /dev/null
@@ -1,5 +0,0 @@
-[D-BUS Service]
-Name=fi.epitest.hostap.WPASupplicant
-Exec=@BINDIR@/wpa_supplicant -u
-User=root
-SystemdService=wpa_supplicant.service
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index b51675b..88cd790 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -109,10 +109,7 @@
 CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
-#CONFIG_EAP_FAST=y
+CONFIG_EAP_FAST=y
 
 # EAP-GTC
 CONFIG_EAP_GTC=y
@@ -127,10 +124,10 @@
 #CONFIG_EAP_PSK=y
 
 # EAP-pwd (secure authentication using only a password)
-#CONFIG_EAP_PWD=y
+CONFIG_EAP_PWD=y
 
 # EAP-PAX
-#CONFIG_EAP_PAX=y
+CONFIG_EAP_PAX=y
 
 # LEAP
 CONFIG_EAP_LEAP=y
@@ -146,18 +143,18 @@
 #CONFIG_USIM_SIMULATOR=y
 
 # EAP-SAKE
-#CONFIG_EAP_SAKE=y
+CONFIG_EAP_SAKE=y
 
 # EAP-GPSK
-#CONFIG_EAP_GPSK=y
+CONFIG_EAP_GPSK=y
 # Include support for optional SHA256 cipher suite in EAP-GPSK
-#CONFIG_EAP_GPSK_SHA256=y
+CONFIG_EAP_GPSK_SHA256=y
 
 # EAP-TNC and related Trusted Network Connect support (experimental)
-#CONFIG_EAP_TNC=y
+CONFIG_EAP_TNC=y
 
 # Wi-Fi Protected Setup (WPS)
-#CONFIG_WPS=y
+CONFIG_WPS=y
 # Enable WPS external registrar functionality
 #CONFIG_WPS_ER=y
 # Disable credentials for an open network by default when acting as a WPS
@@ -167,7 +164,7 @@
 #CONFIG_WPS_NFC=y
 
 # EAP-IKEv2
-#CONFIG_EAP_IKEV2=y
+CONFIG_EAP_IKEV2=y
 
 # EAP-EKE
 #CONFIG_EAP_EKE=y
@@ -235,6 +232,9 @@
 # wpa_passphrase). This saves about 0.5 kB in code size.
 #CONFIG_NO_WPA_PASSPHRASE=y
 
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+CONFIG_SAE=y
+
 # Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
 # This can be used if ap_scan=1 mode is never enabled.
 #CONFIG_NO_SCAN_PROCESSING=y
@@ -299,7 +299,7 @@
 
 # IEEE 802.11w (management frame protection), also known as PMF
 # Driver support is also needed for IEEE 802.11w.
-#CONFIG_IEEE80211W=y
+CONFIG_IEEE80211W=y
 
 # Support Operating Channel Validation
 #CONFIG_OCV=y
@@ -352,16 +352,12 @@
 #CONFIG_NDIS_EVENTS_INTEGRATED=y
 #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
 
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
 # Add support for new DBus control interface
 # (fi.w1.hostap.wpa_supplicant1)
-#CONFIG_CTRL_IFACE_DBUS_NEW=y
+CONFIG_CTRL_IFACE_DBUS_NEW=y
 
 # Add introspection support for new DBus control interface
-#CONFIG_CTRL_IFACE_DBUS_INTRO=y
+CONFIG_CTRL_IFACE_DBUS_INTRO=y
 
 # Add support for loading EAP methods dynamically as shared libraries.
 # When this option is enabled, each EAP method can be either included
@@ -385,13 +381,13 @@
 #CONFIG_DYNAMIC_EAP_METHODS=y
 
 # IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
-#CONFIG_IEEE80211R=y
+CONFIG_IEEE80211R=y
 
 # Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
-#CONFIG_DEBUG_FILE=y
+CONFIG_DEBUG_FILE=y
 
 # Send debug messages to syslog instead of stdout
-#CONFIG_DEBUG_SYSLOG=y
+CONFIG_DEBUG_SYSLOG=y
 # Set syslog facility for debug messages
 #CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
 
@@ -467,11 +463,11 @@
 #CONFIG_GETRANDOM=y
 
 # IEEE 802.11n (High Throughput) support (mainly for AP mode)
-#CONFIG_IEEE80211N=y
+CONFIG_IEEE80211N=y
 
 # IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
 # (depends on CONFIG_IEEE80211N)
-#CONFIG_IEEE80211AC=y
+CONFIG_IEEE80211AC=y
 
 # Wireless Network Management (IEEE Std 802.11v-2011)
 # Note: This is experimental and not complete implementation.
@@ -481,10 +477,10 @@
 # This can be used to enable functionality to improve interworking with
 # external networks (GAS/ANQP to learn more about the networks and network
 # selection based on available credentials).
-#CONFIG_INTERWORKING=y
+CONFIG_INTERWORKING=y
 
 # Hotspot 2.0
-#CONFIG_HS20=y
+CONFIG_HS20=y
 
 # Enable interface matching in wpa_supplicant
 #CONFIG_MATCH_IFACE=y
@@ -497,20 +493,20 @@
 # should be noted that this is mainly aimed at simple cases like
 # WPA2-Personal while more complex configurations like WPA2-Enterprise with an
 # external RADIUS server can be supported with hostapd.
-#CONFIG_AP=y
+CONFIG_AP=y
 
 # P2P (Wi-Fi Direct)
 # This can be used to enable P2P support in wpa_supplicant. See README-P2P for
 # more information on P2P operations.
-#CONFIG_P2P=y
+CONFIG_P2P=y
 
 # Enable TDLS support
 #CONFIG_TDLS=y
 
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
 # program to control the additional information exchanges in the messages.
-#CONFIG_WIFI_DISPLAY=y
+CONFIG_WIFI_DISPLAY=y
 
 # Autoscan
 # This can be used to enable automatic scan support in wpa_supplicant.
@@ -576,7 +572,7 @@
 # Support RSN on IBSS networks
 # This is needed to be able to use mode=1 network profile with proto=RSN and
 # key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
-#CONFIG_IBSS_RSN=y
+CONFIG_IBSS_RSN=y
 
 # External PMKSA cache control
 # This can be used to enable control interface commands that allow the current
@@ -591,7 +587,7 @@
 # operations for roaming within an ESS (same SSID). See the bgscan parameter in
 # the wpa_supplicant.conf file for more details.
 # Periodic background scans based on signal strength
-#CONFIG_BGSCAN_SIMPLE=y
+CONFIG_BGSCAN_SIMPLE=y
 # Learn channels used by the network and try to avoid bgscans on other
 # channels (experimental)
 #CONFIG_BGSCAN_LEARN=y
@@ -599,3 +595,8 @@
 # Opportunistic Wireless Encryption (OWE)
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
+
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+CONFIG_DPP=y
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index ebf102e..aaff150 100644
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -471,7 +471,7 @@
 	  <para>Enable DBus control interface. If enabled, interface
 	  definitions may be omitted. (This is only available
 	  if <command>wpa_supplicant</command> was built with
-	  the <literal>CONFIG_DBUS</literal> option.)</para>
+	  the <literal>CONFIG_CTRL_IFACE_DBUS_NEW</literal> option.)</para>
 	</listitem>
       </varlistentry>
 
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 8877f7a..8a9e444 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -1,7 +1,7 @@
 /*
  * wpa_supplicant - DPP
  * Copyright (c) 2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation
+ * Copyright (c) 2018-2019, The Linux Foundation
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -53,34 +53,6 @@
 static const u8 TRANSACTION_ID = 1;
 
 
-static struct dpp_configurator *
-dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
-{
-	struct dpp_configurator *conf;
-
-	dl_list_for_each(conf, &wpa_s->dpp_configurator,
-			 struct dpp_configurator, list) {
-		if (conf->id == id)
-			return conf;
-	}
-	return NULL;
-}
-
-
-static unsigned int wpas_dpp_next_id(struct wpa_supplicant *wpa_s)
-{
-	struct dpp_bootstrap_info *bi;
-	unsigned int max_id = 0;
-
-	dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
-			 list) {
-		if (bi->id > max_id)
-			max_id = bi->id;
-	}
-	return max_id + 1;
-}
-
-
 /**
  * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
  * @wpa_s: Pointer to wpa_supplicant data
@@ -92,13 +64,10 @@
 	struct dpp_bootstrap_info *bi;
 	struct dpp_authentication *auth = wpa_s->dpp_auth;
 
-	bi = dpp_parse_qr_code(cmd);
+	bi = dpp_add_qr_code(wpa_s->dpp, cmd);
 	if (!bi)
 		return -1;
 
-	bi->id = wpas_dpp_next_id(wpa_s);
-	dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
-
 	if (auth && auth->response_pending &&
 	    dpp_notify_new_qr_code(auth, bi) == 1) {
 		wpa_printf(MSG_DEBUG,
@@ -119,195 +88,6 @@
 }
 
 
-static char * get_param(const char *cmd, const char *param)
-{
-	const char *pos, *end;
-	char *val;
-	size_t len;
-
-	pos = os_strstr(cmd, param);
-	if (!pos)
-		return NULL;
-
-	pos += os_strlen(param);
-	end = os_strchr(pos, ' ');
-	if (end)
-		len = end - pos;
-	else
-		len = os_strlen(pos);
-	val = os_malloc(len + 1);
-	if (!val)
-		return NULL;
-	os_memcpy(val, pos, len);
-	val[len] = '\0';
-	return val;
-}
-
-
-int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd)
-{
-	char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL;
-	char *key = NULL;
-	u8 *privkey = NULL;
-	size_t privkey_len = 0;
-	size_t len;
-	int ret = -1;
-	struct dpp_bootstrap_info *bi;
-
-	bi = os_zalloc(sizeof(*bi));
-	if (!bi)
-		goto fail;
-
-	if (os_strstr(cmd, "type=qrcode"))
-		bi->type = DPP_BOOTSTRAP_QR_CODE;
-	else if (os_strstr(cmd, "type=pkex"))
-		bi->type = DPP_BOOTSTRAP_PKEX;
-	else
-		goto fail;
-
-	chan = get_param(cmd, " chan=");
-	mac = get_param(cmd, " mac=");
-	info = get_param(cmd, " info=");
-	curve = get_param(cmd, " curve=");
-	key = get_param(cmd, " key=");
-
-	if (key) {
-		privkey_len = os_strlen(key) / 2;
-		privkey = os_malloc(privkey_len);
-		if (!privkey ||
-		    hexstr2bin(key, privkey, privkey_len) < 0)
-			goto fail;
-	}
-
-	pk = dpp_keygen(bi, curve, privkey, privkey_len);
-	if (!pk)
-		goto fail;
-
-	len = 4; /* "DPP:" */
-	if (chan) {
-		if (dpp_parse_uri_chan_list(bi, chan) < 0)
-			goto fail;
-		len += 3 + os_strlen(chan); /* C:...; */
-	}
-	if (mac) {
-		if (dpp_parse_uri_mac(bi, mac) < 0)
-			goto fail;
-		len += 3 + os_strlen(mac); /* M:...; */
-	}
-	if (info) {
-		if (dpp_parse_uri_info(bi, info) < 0)
-			goto fail;
-		len += 3 + os_strlen(info); /* I:...; */
-	}
-	len += 4 + os_strlen(pk);
-	bi->uri = os_malloc(len + 1);
-	if (!bi->uri)
-		goto fail;
-	os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
-		    chan ? "C:" : "", chan ? chan : "", chan ? ";" : "",
-		    mac ? "M:" : "", mac ? mac : "", mac ? ";" : "",
-		    info ? "I:" : "", info ? info : "", info ? ";" : "",
-		    pk);
-	bi->id = wpas_dpp_next_id(wpa_s);
-	dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
-	ret = bi->id;
-	bi = NULL;
-fail:
-	os_free(curve);
-	os_free(pk);
-	os_free(chan);
-	os_free(mac);
-	os_free(info);
-	str_clear_free(key);
-	bin_clear_free(privkey, privkey_len);
-	dpp_bootstrap_info_free(bi);
-	return ret;
-}
-
-
-static struct dpp_bootstrap_info *
-dpp_bootstrap_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
-{
-	struct dpp_bootstrap_info *bi;
-
-	dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
-			 list) {
-		if (bi->id == id)
-			return bi;
-	}
-	return NULL;
-}
-
-
-static int dpp_bootstrap_del(struct wpa_supplicant *wpa_s, unsigned int id)
-{
-	struct dpp_bootstrap_info *bi, *tmp;
-	int found = 0;
-
-	dl_list_for_each_safe(bi, tmp, &wpa_s->dpp_bootstrap,
-			      struct dpp_bootstrap_info, list) {
-		if (id && bi->id != id)
-			continue;
-		found = 1;
-		dl_list_del(&bi->list);
-		dpp_bootstrap_info_free(bi);
-	}
-
-	if (id == 0)
-		return 0; /* flush succeeds regardless of entries found */
-	return found ? 0 : -1;
-}
-
-
-int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id)
-{
-	unsigned int id_val;
-
-	if (os_strcmp(id, "*") == 0) {
-		id_val = 0;
-	} else {
-		id_val = atoi(id);
-		if (id_val == 0)
-			return -1;
-	}
-
-	return dpp_bootstrap_del(wpa_s, id_val);
-}
-
-
-const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
-					unsigned int id)
-{
-	struct dpp_bootstrap_info *bi;
-
-	bi = dpp_bootstrap_get_id(wpa_s, id);
-	if (!bi)
-		return NULL;
-	return bi->uri;
-}
-
-
-int wpas_dpp_bootstrap_info(struct wpa_supplicant *wpa_s, int id,
-			    char *reply, int reply_size)
-{
-	struct dpp_bootstrap_info *bi;
-
-	bi = dpp_bootstrap_get_id(wpa_s, id);
-	if (!bi)
-		return -1;
-	return os_snprintf(reply, reply_size, "type=%s\n"
-			   "mac_addr=" MACSTR "\n"
-			   "info=%s\n"
-			   "num_freq=%u\n"
-			   "curve=%s\n",
-			   dpp_bootstrap_type_txt(bi->type),
-			   MAC2STR(bi->mac_addr),
-			   bi->info ? bi->info : "",
-			   bi->num_freq,
-			   bi->curve->name);
-}
-
-
 static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx)
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -365,6 +145,18 @@
 }
 
 
+static void wpas_dpp_try_to_connect(struct wpa_supplicant *wpa_s)
+{
+	wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
+	wpa_s->disconnected = 0;
+	wpa_s->reassociate = 1;
+	wpa_s->scan_runs = 0;
+	wpa_s->normal_scans = 0;
+	wpa_supplicant_cancel_sched_scan(wpa_s);
+	wpa_supplicant_req_scan(wpa_s, 0, 0);
+}
+
+
 static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
 			       unsigned int freq, const u8 *dst,
 			       const u8 *src, const u8 *bssid,
@@ -388,6 +180,17 @@
 		return;
 	}
 
+#ifdef CONFIG_DPP2
+	if (auth->connect_on_tx_status) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: Try to connect after completed configuration result");
+		wpas_dpp_try_to_connect(wpa_s);
+		dpp_auth_deinit(wpa_s->dpp_auth);
+		wpa_s->dpp_auth = NULL;
+		return;
+	}
+#endif /* CONFIG_DPP2 */
+
 	if (wpa_s->dpp_auth->remove_on_tx_status) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Terminate authentication exchange due to an earlier error");
@@ -529,176 +332,6 @@
 }
 
 
-static int wpas_dpp_set_configurator(struct wpa_supplicant *wpa_s,
-				     struct dpp_authentication *auth,
-				     const char *cmd)
-{
-	const char *pos, *end;
-	struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
-	struct dpp_configurator *conf = NULL;
-	u8 ssid[32] = { "test" };
-	size_t ssid_len = 4;
-	char pass[64] = { };
-	size_t pass_len = 0;
-	u8 psk[PMK_LEN];
-	int psk_set = 0;
-	char *group_id = NULL;
-
-	if (!cmd)
-		return 0;
-
-	wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
-	pos = os_strstr(cmd, " ssid=");
-	if (pos) {
-		pos += 6;
-		end = os_strchr(pos, ' ');
-		ssid_len = end ? (size_t) (end - pos) : os_strlen(pos);
-		ssid_len /= 2;
-		if (ssid_len > sizeof(ssid) ||
-		    hexstr2bin(pos, ssid, ssid_len) < 0)
-			goto fail;
-	}
-
-	pos = os_strstr(cmd, " pass=");
-	if (pos) {
-		pos += 6;
-		end = os_strchr(pos, ' ');
-		pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
-		pass_len /= 2;
-		if (pass_len > sizeof(pass) - 1 || pass_len < 8 ||
-		    hexstr2bin(pos, (u8 *) pass, pass_len) < 0)
-			goto fail;
-	}
-
-	pos = os_strstr(cmd, " psk=");
-	if (pos) {
-		pos += 5;
-		if (hexstr2bin(pos, psk, PMK_LEN) < 0)
-			goto fail;
-		psk_set = 1;
-	}
-
-	pos = os_strstr(cmd, " group_id=");
-	if (pos) {
-		size_t group_id_len;
-
-		pos += 10;
-		end = os_strchr(pos, ' ');
-		group_id_len = end ? (size_t) (end - pos) : os_strlen(pos);
-		group_id = os_malloc(group_id_len + 1);
-		if (!group_id)
-			goto fail;
-		os_memcpy(group_id, pos, group_id_len);
-		group_id[group_id_len] = '\0';
-	}
-
-	if (os_strstr(cmd, " conf=sta-")) {
-		conf_sta = os_zalloc(sizeof(struct dpp_configuration));
-		if (!conf_sta)
-			goto fail;
-		os_memcpy(conf_sta->ssid, ssid, ssid_len);
-		conf_sta->ssid_len = ssid_len;
-		if (os_strstr(cmd, " conf=sta-psk") ||
-		    os_strstr(cmd, " conf=sta-sae") ||
-		    os_strstr(cmd, " conf=sta-psk-sae")) {
-			if (os_strstr(cmd, " conf=sta-psk-sae"))
-				conf_sta->akm = DPP_AKM_PSK_SAE;
-			else if (os_strstr(cmd, " conf=sta-sae"))
-				conf_sta->akm = DPP_AKM_SAE;
-			else
-				conf_sta->akm = DPP_AKM_PSK;
-			if (psk_set) {
-				os_memcpy(conf_sta->psk, psk, PMK_LEN);
-			} else if (pass_len > 0) {
-				conf_sta->passphrase = os_strdup(pass);
-				if (!conf_sta->passphrase)
-					goto fail;
-			} else {
-				goto fail;
-			}
-		} else if (os_strstr(cmd, " conf=sta-dpp")) {
-			conf_sta->akm = DPP_AKM_DPP;
-		} else {
-			goto fail;
-		}
-		if (os_strstr(cmd, " group_id=")) {
-			conf_sta->group_id = group_id;
-			group_id = NULL;
-		}
-	}
-
-	if (os_strstr(cmd, " conf=ap-")) {
-		conf_ap = os_zalloc(sizeof(struct dpp_configuration));
-		if (!conf_ap)
-			goto fail;
-		os_memcpy(conf_ap->ssid, ssid, ssid_len);
-		conf_ap->ssid_len = ssid_len;
-		if (os_strstr(cmd, " conf=ap-psk") ||
-		    os_strstr(cmd, " conf=ap-sae") ||
-		    os_strstr(cmd, " conf=ap-psk-sae")) {
-			if (os_strstr(cmd, " conf=ap-psk-sae"))
-				conf_ap->akm = DPP_AKM_PSK_SAE;
-			else if (os_strstr(cmd, " conf=ap-sae"))
-				conf_ap->akm = DPP_AKM_SAE;
-			else
-				conf_ap->akm = DPP_AKM_PSK;
-			if (psk_set) {
-				os_memcpy(conf_ap->psk, psk, PMK_LEN);
-			} else {
-				conf_ap->passphrase = os_strdup(pass);
-				if (!conf_ap->passphrase)
-					goto fail;
-			}
-		} else if (os_strstr(cmd, " conf=ap-dpp")) {
-			conf_ap->akm = DPP_AKM_DPP;
-		} else {
-			goto fail;
-		}
-		if (os_strstr(cmd, " group_id=")) {
-			conf_ap->group_id = group_id;
-			group_id = NULL;
-		}
-	}
-
-	pos = os_strstr(cmd, " expiry=");
-	if (pos) {
-		long int val;
-
-		pos += 8;
-		val = strtol(pos, NULL, 0);
-		if (val <= 0)
-			goto fail;
-		if (conf_sta)
-			conf_sta->netaccesskey_expiry = val;
-		if (conf_ap)
-			conf_ap->netaccesskey_expiry = val;
-	}
-
-	pos = os_strstr(cmd, " configurator=");
-	if (pos) {
-		pos += 14;
-		conf = dpp_configurator_get_id(wpa_s, atoi(pos));
-		if (!conf) {
-			wpa_printf(MSG_INFO,
-				   "DPP: Could not find the specified configurator");
-			goto fail;
-		}
-	}
-	auth->conf_sta = conf_sta;
-	auth->conf_ap = conf_ap;
-	auth->conf = conf;
-	os_free(group_id);
-	return 0;
-
-fail:
-	wpa_msg(wpa_s, MSG_INFO, "DPP: Failed to set configurator parameters");
-	dpp_configuration_free(conf_sta);
-	dpp_configuration_free(conf_ap);
-	os_free(group_id);
-	return -1;
-}
-
-
 static void wpas_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -812,7 +445,7 @@
 	if (!pos)
 		return -1;
 	pos += 6;
-	peer_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
+	peer_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
 	if (!peer_bi) {
 		wpa_printf(MSG_INFO,
 			   "DPP: Could not find bootstrapping info for the identified peer");
@@ -822,7 +455,7 @@
 	pos = os_strstr(cmd, " own=");
 	if (pos) {
 		pos += 5;
-		own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
+		own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
 		if (!own_bi) {
 			wpa_printf(MSG_INFO,
 				   "DPP: Could not find bootstrapping info for the identified local entry");
@@ -875,7 +508,7 @@
 	if (!wpa_s->dpp_auth)
 		goto fail;
 	wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
-	if (wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth, cmd) < 0) {
+	if (dpp_set_configurator(wpa_s->dpp, wpa_s, wpa_s->dpp_auth, cmd) < 0) {
 		dpp_auth_deinit(wpa_s->dpp_auth);
 		wpa_s->dpp_auth = NULL;
 		goto fail;
@@ -1059,7 +692,10 @@
 {
 	const u8 *r_bootstrap, *i_bootstrap;
 	u16 r_bootstrap_len, i_bootstrap_len;
-	struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
+	struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
+
+	if (!wpa_s->dpp)
+		return;
 
 	wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
 		   MAC2STR(src));
@@ -1086,28 +722,8 @@
 
 	/* Try to find own and peer bootstrapping key matches based on the
 	 * received hash values */
-	dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
-			 list) {
-		if (!own_bi && bi->own &&
-		    os_memcmp(bi->pubkey_hash, r_bootstrap,
-			      SHA256_MAC_LEN) == 0) {
-			wpa_printf(MSG_DEBUG,
-				   "DPP: Found matching own bootstrapping information");
-			own_bi = bi;
-		}
-
-		if (!peer_bi && !bi->own &&
-		    os_memcmp(bi->pubkey_hash, i_bootstrap,
-			      SHA256_MAC_LEN) == 0) {
-			wpa_printf(MSG_DEBUG,
-				   "DPP: Found matching peer bootstrapping information");
-			peer_bi = bi;
-		}
-
-		if (own_bi && peer_bi)
-			break;
-	}
-
+	dpp_bootstrap_find_pair(wpa_s->dpp, i_bootstrap, r_bootstrap,
+				&own_bi, &peer_bi);
 	if (!own_bi) {
 		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
 			"No matching own bootstrapping key found - ignore message");
@@ -1130,8 +746,8 @@
 		return;
 	}
 	wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
-	if (wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth,
-				      wpa_s->dpp_configurator_params) < 0) {
+	if (dpp_set_configurator(wpa_s->dpp, wpa_s, wpa_s->dpp_auth,
+				 wpa_s->dpp_configurator_params) < 0) {
 		dpp_auth_deinit(wpa_s->dpp_auth);
 		wpa_s->dpp_auth = NULL;
 		return;
@@ -1168,6 +784,27 @@
 {
 	struct wpa_ssid *ssid;
 
+#ifdef CONFIG_DPP2
+	if (auth->akm == DPP_AKM_SAE) {
+#ifdef CONFIG_SAE
+		struct wpa_driver_capa capa;
+		int res;
+
+		res = wpa_drv_get_capa(wpa_s, &capa);
+		if (res == 0 &&
+		    !(capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) &&
+		    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
+			wpa_printf(MSG_DEBUG,
+				   "DPP: SAE not supported by the driver");
+			return NULL;
+		}
+#else /* CONFIG_SAE */
+		wpa_printf(MSG_DEBUG, "DPP: SAE not supported in the build");
+		return NULL;
+#endif /* CONFIG_SAE */
+	}
+#endif /* CONFIG_DPP2 */
+
 	ssid = wpa_config_add_network(wpa_s->conf);
 	if (!ssid)
 		return NULL;
@@ -1210,12 +847,14 @@
 		ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry;
 	}
 
-	if (!auth->connector) {
-		ssid->key_mgmt = 0;
-		if (auth->akm == DPP_AKM_PSK || auth->akm == DPP_AKM_PSK_SAE)
+	if (!auth->connector || dpp_akm_psk(auth->akm) ||
+	    dpp_akm_sae(auth->akm)) {
+		if (!auth->connector)
+			ssid->key_mgmt = 0;
+		if (dpp_akm_psk(auth->akm))
 			ssid->key_mgmt |= WPA_KEY_MGMT_PSK |
 				WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK;
-		if (auth->akm == DPP_AKM_SAE || auth->akm == DPP_AKM_PSK_SAE)
+		if (dpp_akm_sae(auth->akm))
 			ssid->key_mgmt |= WPA_KEY_MGMT_SAE |
 				WPA_KEY_MGMT_FT_SAE;
 		ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
@@ -1239,39 +878,50 @@
 }
 
 
-static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
-				    struct dpp_authentication *auth)
+static int wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
+				   struct dpp_authentication *auth)
 {
 	struct wpa_ssid *ssid;
 
 	if (wpa_s->conf->dpp_config_processing < 1)
-		return;
+		return 0;
 
 	ssid = wpas_dpp_add_network(wpa_s, auth);
 	if (!ssid)
-		return;
+		return -1;
 
 	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
 
 	wpas_notify_dpp_config_received(wpa_s, ssid);
 
-	if (wpa_s->conf->dpp_config_processing < 2) {
-		return;
-	}
+	if (wpa_s->conf->dpp_config_processing == 2)
+		ssid->disabled = 0;
 
-	wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
-	ssid->disabled = 0;
-	wpa_s->disconnected = 0;
-	wpa_s->reassociate = 1;
-	wpa_s->scan_runs = 0;
-	wpa_s->normal_scans = 0;
-	wpa_supplicant_cancel_sched_scan(wpa_s);
-	wpa_supplicant_req_scan(wpa_s, 0, 0);
+#ifndef CONFIG_NO_CONFIG_WRITE
+	if (wpa_s->conf->update_config &&
+	    wpa_config_write(wpa_s->confname, wpa_s->conf))
+		wpa_printf(MSG_DEBUG, "DPP: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
+
+	if (wpa_s->conf->dpp_config_processing < 2)
+		return 0;
+
+#ifdef CONFIG_DPP2
+	if (auth->peer_version >= 2) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
+		auth->connect_on_tx_status = 1;
+		return 0;
+	}
+#endif /* CONFIG_DPP2 */
+
+	wpas_dpp_try_to_connect(wpa_s);
+	return 0;
 }
 
 
-static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
-				       struct dpp_authentication *auth)
+static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
+				      struct dpp_authentication *auth)
 {
 	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
 	if (auth->ssid_len)
@@ -1323,7 +973,7 @@
 		}
 	}
 
-	wpas_dpp_process_config(wpa_s, auth);
+	return wpas_dpp_process_config(wpa_s, auth);
 }
 
 
@@ -1335,6 +985,8 @@
 	struct wpa_supplicant *wpa_s = ctx;
 	const u8 *pos;
 	struct dpp_authentication *auth = wpa_s->dpp_auth;
+	int res;
+	enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
 
 	wpa_s->dpp_gas_dialog_token = -1;
 
@@ -1372,14 +1024,48 @@
 		goto fail;
 	}
 
-	wpas_dpp_handle_config_obj(wpa_s, auth);
-	dpp_auth_deinit(wpa_s->dpp_auth);
-	wpa_s->dpp_auth = NULL;
-	return;
+	res = wpas_dpp_handle_config_obj(wpa_s, auth);
+	if (res < 0)
+		goto fail;
 
+	status = DPP_STATUS_OK;
+#ifdef CONFIG_TESTING_OPTIONS
+	if (dpp_test == DPP_TEST_REJECT_CONFIG) {
+		wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
+		status = DPP_STATUS_CONFIG_REJECTED;
+	}
+#endif /* CONFIG_TESTING_OPTIONS */
 fail:
-	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
-	wpas_notify_dpp_configuration_failure(wpa_s);
+	if (status != DPP_STATUS_OK) {
+		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+		wpas_notify_dpp_configuration_failure(wpa_s);
+	}
+#ifdef CONFIG_DPP2
+	if (auth->peer_version >= 2 &&
+	    auth->conf_resp_status == DPP_STATUS_OK) {
+		struct wpabuf *msg;
+
+		wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
+		msg = dpp_build_conf_result(auth, status);
+		if (!msg)
+			goto fail2;
+
+		wpa_msg(wpa_s, MSG_INFO,
+			DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
+			MAC2STR(addr), auth->curr_freq,
+			DPP_PA_CONFIGURATION_RESULT);
+		offchannel_send_action(wpa_s, auth->curr_freq,
+				       addr, wpa_s->own_addr, broadcast,
+				       wpabuf_head(msg),
+				       wpabuf_len(msg),
+				       500, wpas_dpp_tx_status, 0);
+		wpabuf_free(msg);
+
+		/* This exchange will be terminated in the TX status handler */
+		return;
+	}
+fail2:
+#endif /* CONFIG_DPP2 */
 	dpp_auth_deinit(wpa_s->dpp_auth);
 	wpa_s->dpp_auth = NULL;
 }
@@ -1388,7 +1074,7 @@
 static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
 {
 	struct dpp_authentication *auth = wpa_s->dpp_auth;
-	struct wpabuf *buf, *conf_req;
+	struct wpabuf *buf;
 	char json[100];
 	int res;
 
@@ -1409,34 +1095,13 @@
 	offchannel_send_action_done(wpa_s);
 	wpas_dpp_listen_stop(wpa_s);
 
-	conf_req = dpp_build_conf_req(auth, json);
-	if (!conf_req) {
+	buf = dpp_build_conf_req(auth, json);
+	if (!buf) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: No configuration request data available");
 		return;
 	}
 
-	buf = gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req));
-	if (!buf) {
-		wpabuf_free(conf_req);
-		return;
-	}
-
-	/* Advertisement Protocol IE */
-	wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
-	wpabuf_put_u8(buf, 8); /* Length */
-	wpabuf_put_u8(buf, 0x7f);
-	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
-	wpabuf_put_u8(buf, 5);
-	wpabuf_put_be24(buf, OUI_WFA);
-	wpabuf_put_u8(buf, DPP_OUI_TYPE);
-	wpabuf_put_u8(buf, 0x01);
-
-	/* GAS Query */
-	wpabuf_put_le16(buf, wpabuf_len(conf_req));
-	wpabuf_put_buf(buf, conf_req);
-	wpabuf_free(conf_req);
-
 	wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
 		   MAC2STR(auth->peer_mac_addr), auth->curr_freq);
 
@@ -1565,6 +1230,62 @@
 }
 
 
+#ifdef CONFIG_DPP2
+
+static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx,
+						void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+	if (!auth || !auth->waiting_conf_result)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP: Timeout while waiting for Configuration Result");
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+	dpp_auth_deinit(auth);
+	wpa_s->dpp_auth = NULL;
+}
+
+
+static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
+				    const u8 *hdr, const u8 *buf, size_t len)
+{
+	struct dpp_authentication *auth = wpa_s->dpp_auth;
+	enum dpp_status_error status;
+
+	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
+		   MAC2STR(src));
+
+	if (!auth || !auth->waiting_conf_result) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: No DPP Configuration waiting for result - drop");
+		return;
+	}
+
+	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
+		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
+			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
+		return;
+	}
+
+	status = dpp_conf_result_rx(auth, hdr, buf, len);
+
+	offchannel_send_action_done(wpa_s);
+	wpas_dpp_listen_stop(wpa_s);
+	if (status == DPP_STATUS_OK)
+		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
+	else
+		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
+	dpp_auth_deinit(auth);
+	wpa_s->dpp_auth = NULL;
+	eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
+}
+
+#endif /* CONFIG_DPP2 */
+
+
 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
 				       const u8 *src,
 				       const u8 *buf, size_t len)
@@ -1925,27 +1646,12 @@
 wpas_dpp_pkex_finish(struct wpa_supplicant *wpa_s, const u8 *peer,
 		     unsigned int freq)
 {
-	struct dpp_pkex *pkex = wpa_s->dpp_pkex;
 	struct dpp_bootstrap_info *bi;
 
-	bi = os_zalloc(sizeof(*bi));
+	bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
 	if (!bi)
 		return NULL;
-	bi->id = wpas_dpp_next_id(wpa_s);
-	bi->type = DPP_BOOTSTRAP_PKEX;
-	os_memcpy(bi->mac_addr, peer, ETH_ALEN);
-	bi->num_freq = 1;
-	bi->freq[0] = freq;
-	bi->curve = pkex->own_bi->curve;
-	bi->pubkey = pkex->peer_bootstrap_key;
-	pkex->peer_bootstrap_key = NULL;
-	dpp_pkex_free(pkex);
 	wpa_s->dpp_pkex = NULL;
-	if (dpp_bootstrap_key_hash(bi) < 0) {
-		dpp_bootstrap_info_free(bi);
-		return NULL;
-	}
-	dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
 	return bi;
 }
 
@@ -2108,6 +1814,11 @@
 		wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s, src, hdr, buf, len,
 						    freq);
 		break;
+#ifdef CONFIG_DPP2
+	case DPP_PA_CONFIGURATION_RESULT:
+		wpas_dpp_rx_conf_result(wpa_s, src, hdr, buf, len);
+		break;
+#endif /* CONFIG_DPP2 */
 	default:
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Ignored unsupported frame subtype %d", type);
@@ -2179,6 +1890,21 @@
 		   ok);
 	eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
+#ifdef CONFIG_DPP2
+	if (ok && auth->peer_version >= 2 &&
+	    auth->conf_resp_status == DPP_STATUS_OK) {
+		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
+		auth->waiting_conf_result = 1;
+		auth->conf_resp = NULL;
+		wpabuf_free(resp);
+		eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout,
+				     wpa_s, NULL);
+		eloop_register_timeout(2, 0,
+				       wpas_dpp_config_result_wait_timeout,
+				       wpa_s, NULL);
+		return;
+	}
+#endif /* CONFIG_DPP2 */
 	offchannel_send_action_done(wpa_s);
 	wpas_dpp_listen_stop(wpa_s);
 	if (ok) {
@@ -2195,93 +1921,6 @@
 }
 
 
-static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant *wpa_s)
-{
-	struct dpp_configurator *conf;
-	unsigned int max_id = 0;
-
-	dl_list_for_each(conf, &wpa_s->dpp_configurator,
-			 struct dpp_configurator, list) {
-		if (conf->id > max_id)
-			max_id = conf->id;
-	}
-	return max_id + 1;
-}
-
-
-int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd)
-{
-	char *curve = NULL;
-	char *key = NULL;
-	u8 *privkey = NULL;
-	size_t privkey_len = 0;
-	int ret = -1;
-	struct dpp_configurator *conf = NULL;
-
-	curve = get_param(cmd, " curve=");
-	key = get_param(cmd, " key=");
-
-	if (key) {
-		privkey_len = os_strlen(key) / 2;
-		privkey = os_malloc(privkey_len);
-		if (!privkey ||
-		    hexstr2bin(key, privkey, privkey_len) < 0)
-			goto fail;
-	}
-
-	conf = dpp_keygen_configurator(curve, privkey, privkey_len);
-	if (!conf)
-		goto fail;
-
-	conf->id = wpas_dpp_next_configurator_id(wpa_s);
-	dl_list_add(&wpa_s->dpp_configurator, &conf->list);
-	ret = conf->id;
-	conf = NULL;
-fail:
-	os_free(curve);
-	str_clear_free(key);
-	bin_clear_free(privkey, privkey_len);
-	dpp_configurator_free(conf);
-	return ret;
-}
-
-
-static int dpp_configurator_del(struct wpa_supplicant *wpa_s, unsigned int id)
-{
-	struct dpp_configurator *conf, *tmp;
-	int found = 0;
-
-	dl_list_for_each_safe(conf, tmp, &wpa_s->dpp_configurator,
-			      struct dpp_configurator, list) {
-		if (id && conf->id != id)
-			continue;
-		found = 1;
-		dl_list_del(&conf->list);
-		dpp_configurator_free(conf);
-	}
-
-	if (id == 0)
-		return 0; /* flush succeeds regardless of entries found */
-	return found ? 0 : -1;
-}
-
-
-int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id)
-{
-	unsigned int id_val;
-
-	if (os_strcmp(id, "*") == 0) {
-		id_val = 0;
-	} else {
-		id_val = atoi(id);
-		if (id_val == 0)
-			return -1;
-	}
-
-	return dpp_configurator_del(wpa_s, id_val);
-}
-
-
 int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
 {
 	struct dpp_authentication *auth;
@@ -2294,11 +1933,9 @@
 
 	curve = get_param(cmd, " curve=");
 	wpas_dpp_set_testing_options(wpa_s, auth);
-	if (wpas_dpp_set_configurator(wpa_s, auth, cmd) == 0 &&
-	    dpp_configurator_own_config(auth, curve, 0) == 0) {
-		wpas_dpp_handle_config_obj(wpa_s, auth);
-		ret = 0;
-	}
+	if (dpp_set_configurator(wpa_s->dpp, wpa_s, auth, cmd) == 0 &&
+	    dpp_configurator_own_config(auth, curve, 0) == 0)
+		ret = wpas_dpp_handle_config_obj(wpa_s, auth);
 
 	dpp_auth_deinit(auth);
 	os_free(curve);
@@ -2307,19 +1944,6 @@
 }
 
 
-int wpas_dpp_configurator_get_key(struct wpa_supplicant *wpa_s, unsigned int id,
-				  char *buf, size_t buflen)
-{
-	struct dpp_configurator *conf;
-
-	conf = dpp_configurator_get_id(wpa_s, id);
-	if (!conf)
-		return -1;
-
-	return dpp_configurator_get_key(conf, buf, buflen);
-}
-
-
 static void
 wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
 				unsigned int freq, const u8 *dst,
@@ -2347,9 +1971,15 @@
 	struct os_time now;
 	struct wpabuf *msg;
 	unsigned int wait_time;
+	const u8 *rsn;
+	struct wpa_ie_data ied;
 
 	if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss)
 		return 0; /* Not using DPP AKM - continue */
+	rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+	if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
+	    !(ied.key_mgmt & WPA_KEY_MGMT_DPP))
+		return 0; /* AP does not support DPP AKM - continue */
 	if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid))
 		return 0; /* PMKSA exists for DPP AKM - continue */
 
@@ -2462,7 +2092,7 @@
 	if (!pos)
 		return -1;
 	pos += 5;
-	own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
+	own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
 	if (!own_bi) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Identified bootstrap info not found");
@@ -2595,10 +2225,8 @@
 				sizeof(adv_proto_id), wpas_dpp_gas_req_handler,
 				wpas_dpp_gas_status_handler, wpa_s) < 0)
 		return -1;
-	dl_list_init(&wpa_s->dpp_bootstrap);
-	dl_list_init(&wpa_s->dpp_configurator);
-	wpa_s->dpp_init_done = 1;
-	return 0;
+	wpa_s->dpp = dpp_global_init();
+	return wpa_s->dpp ? 0 : -1;
 }
 
 
@@ -2613,16 +2241,20 @@
 	wpa_s->dpp_groups_override = NULL;
 	wpa_s->dpp_ignore_netaccesskey_mismatch = 0;
 #endif /* CONFIG_TESTING_OPTIONS */
-	if (!wpa_s->dpp_init_done)
+	if (!wpa_s->dpp)
 		return;
+	dpp_global_clear(wpa_s->dpp);
 	eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
+#ifdef CONFIG_DPP2
+	eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
+	dpp_pfs_free(wpa_s->dpp_pfs);
+	wpa_s->dpp_pfs = NULL;
+#endif /* CONFIG_DPP2 */
 	offchannel_send_action_done(wpa_s);
 	wpas_dpp_listen_stop(wpa_s);
-	dpp_bootstrap_del(wpa_s, 0);
-	dpp_configurator_del(wpa_s, 0);
 	wpas_dpp_stop(wpa_s);
 	wpas_dpp_pkex_remove(wpa_s, "*");
 	os_memset(wpa_s->dpp_intro_bssid, 0, ETH_ALEN);
diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h
index 5a4f06e..ecb7a7d 100644
--- a/wpa_supplicant/dpp_supplicant.h
+++ b/wpa_supplicant/dpp_supplicant.h
@@ -10,12 +10,6 @@
 #define DPP_SUPPLICANT_H
 
 int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id);
-const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
-					unsigned int id);
-int wpas_dpp_bootstrap_info(struct wpa_supplicant *wpa_s, int id,
-			    char *reply, int reply_size);
 int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd);
 void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s);
@@ -23,11 +17,7 @@
 					  unsigned int freq);
 void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
 			const u8 *buf, size_t len, unsigned int freq);
-int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id);
 int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_configurator_get_key(struct wpa_supplicant *wpa_s, unsigned int id,
-				  char *buf, size_t buflen);
 int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id);
 void wpas_dpp_stop(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8ede2bb..632252c 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - Driver event processing
- * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -29,6 +29,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/gas_server.h"
+#include "common/dpp.h"
 #include "crypto/random.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
@@ -559,6 +560,10 @@
 					"   skip RSN IE - parse failed");
 			break;
 		}
+		if (!ie.has_pairwise)
+			ie.pairwise_cipher = wpa_default_rsn_cipher(bss->freq);
+		if (!ie.has_group)
+			ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
 
 		if (wep_ok &&
 		    (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
@@ -1899,7 +1904,7 @@
 	if (sme_proc_obss_scan(wpa_s) > 0)
 		goto scan_work_done;
 
-	if (own_request &&
+	if (own_request && data &&
 	    wpas_beacon_rep_scan_process(wpa_s, scan_res, &data->scan_info) > 0)
 		goto scan_work_done;
 
@@ -2305,6 +2310,13 @@
 	}
 
 	if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
+		if ((map_sub_elem[2] & MULTI_AP_FRONTHAUL_BSS) &&
+		    wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+			wpa_printf(MSG_INFO,
+				   "WPS active, accepting fronthaul-only BSS");
+			/* Don't set 4addr mode in this case, so just return */
+			return;
+		}
 		wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
 		goto fail;
 	}
@@ -2409,6 +2421,26 @@
 		wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz",
 			data->assoc_info.freq);
 
+	wpa_s->connection_set = 0;
+	if (data->assoc_info.req_ies && data->assoc_info.resp_ies) {
+		struct ieee802_11_elems req_elems, resp_elems;
+
+		if (ieee802_11_parse_elems(data->assoc_info.req_ies,
+					   data->assoc_info.req_ies_len,
+					   &req_elems, 0) != ParseFailed &&
+		    ieee802_11_parse_elems(data->assoc_info.resp_ies,
+					   data->assoc_info.resp_ies_len,
+					   &resp_elems, 0) != ParseFailed) {
+			wpa_s->connection_set = 1;
+			wpa_s->connection_ht = req_elems.ht_capabilities &&
+				resp_elems.ht_capabilities;
+			wpa_s->connection_vht = req_elems.vht_capabilities &&
+				resp_elems.vht_capabilities;
+			wpa_s->connection_he = req_elems.he_capabilities &&
+				resp_elems.he_capabilities;
+		}
+	}
+
 	p = data->assoc_info.req_ies;
 	l = data->assoc_info.req_ies_len;
 
@@ -2467,6 +2499,28 @@
 	}
 #endif /* CONFIG_OWE */
 
+#ifdef CONFIG_DPP2
+	wpa_sm_set_dpp_z(wpa_s->wpa, NULL);
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && wpa_s->dpp_pfs) {
+		struct ieee802_11_elems elems;
+
+		if (ieee802_11_parse_elems(data->assoc_info.resp_ies,
+					   data->assoc_info.resp_ies_len,
+					   &elems, 0) == ParseFailed ||
+		    !elems.owe_dh)
+			goto no_pfs;
+		if (dpp_pfs_process(wpa_s->dpp_pfs, elems.owe_dh,
+				    elems.owe_dh_len) < 0) {
+			wpa_supplicant_deauthenticate(wpa_s,
+						      WLAN_REASON_UNSPECIFIED);
+			return -1;
+		}
+
+		wpa_sm_set_dpp_z(wpa_s->wpa, wpa_s->dpp_pfs->secret);
+	}
+no_pfs:
+#endif /* CONFIG_DPP2 */
+
 #ifdef CONFIG_IEEE80211R
 #ifdef CONFIG_SME
 	if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
@@ -4811,7 +4865,7 @@
 		break;
 	case EVENT_WPS_BUTTON_PUSHED:
 #ifdef CONFIG_WPS
-		wpas_wps_start_pbc(wpa_s, NULL, 0);
+		wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
 #endif /* CONFIG_WPS */
 		break;
 	case EVENT_AVOID_FREQUENCIES:
diff --git a/wpa_supplicant/examples/wpas-test.py b/wpa_supplicant/examples/wpas-test.py
deleted file mode 100755
index bdd16a8..0000000
--- a/wpa_supplicant/examples/wpas-test.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-import sys, os
-import time
-
-WPAS_DBUS_SERVICE = "fi.epitest.hostap.WPASupplicant"
-WPAS_DBUS_INTERFACE = "fi.epitest.hostap.WPASupplicant"
-WPAS_DBUS_OPATH = "/fi/epitest/hostap/WPASupplicant"
-
-WPAS_DBUS_INTERFACES_INTERFACE = "fi.epitest.hostap.WPASupplicant.Interface"
-WPAS_DBUS_INTERFACES_OPATH = "/fi/epitest/hostap/WPASupplicant/Interfaces"
-WPAS_DBUS_BSSID_INTERFACE = "fi.epitest.hostap.WPASupplicant.BSSID"
-
-def byte_array_to_string(s):
-	import urllib
-	r = ""    
-	for c in s:
-		if c >= 32 and c < 127:
-			r += "%c" % c
-		else:
-			r += urllib.quote(chr(c))
-	return r
-
-def main():
-	if len(sys.argv) != 2:
-		print("Usage: wpas-test.py <interface>")
-		os._exit(1)
-
-	ifname = sys.argv[1]
-
-	bus = dbus.SystemBus()
-	wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
-	wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
-
-	# See if wpa_supplicant already knows about this interface
-	path = None
-	try:
-		path = wpas.getInterface(ifname)
-	except dbus.dbus_bindings.DBusException as exc:
-		if str(exc) != "wpa_supplicant knows nothing about this interface.":
-			raise exc
-		try:
-			path = wpas.addInterface(ifname, {'driver': dbus.Variant('wext')})
-		except dbus.dbus_bindings.DBusException as exc:
-			if str(exc) != "wpa_supplicant already controls this interface.":
-				raise exc
-
-	if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
-	iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
-	iface.scan()
-	# Should really wait for the "scanResults" signal instead of sleeping
-	time.sleep(5)
-	res = iface.scanResults()
-
-	print("Scanned wireless networks:")
-	for opath in res:
-		net_obj = bus.get_object(WPAS_DBUS_SERVICE, opath)
-		net = dbus.Interface(net_obj, WPAS_DBUS_BSSID_INTERFACE)
-		props = net.properties()
-
-		# Convert the byte-array for SSID and BSSID to printable strings
-		bssid = ""
-		for item in props["bssid"]:
-			bssid = bssid + ":%02x" % item
-		bssid = bssid[1:]
-		ssid = byte_array_to_string(props["ssid"])
-		wpa = "no"
-		if props.has_key("wpaie"):
-			wpa = "yes"
-		wpa2 = "no"
-		if props.has_key("rsnie"):
-			wpa2 = "yes"
-		freq = 0
-		if props.has_key("frequency"):
-			freq = props["frequency"]
-		caps = props["capabilities"]
-		qual = props["quality"]
-		level = props["level"]
-		noise = props["noise"]
-		maxrate = props["maxrate"] / 1000000
-
-		print("  %s  ::  ssid='%s'  wpa=%s  wpa2=%s  quality=%d%%  rate=%d  freq=%d" % (bssid, ssid, wpa, wpa2, qual, maxrate, freq))
-
-	wpas.removeInterface(dbus.ObjectPath(path))
-	# Should fail here with unknown interface error
-	iface.scan()
-
-if __name__ == "__main__":
-	main()
-
diff --git a/wpa_supplicant/hidl/1.2/p2p_iface.cpp b/wpa_supplicant/hidl/1.2/p2p_iface.cpp
index bcd96c3..7acb0d3 100644
--- a/wpa_supplicant/hidl/1.2/p2p_iface.cpp
+++ b/wpa_supplicant/hidl/1.2/p2p_iface.cpp
@@ -1406,7 +1406,7 @@
 		return {SupplicantStatusCode::SUCCESS, ""};
 	}
 #endif /* CONFIG_AP */
-	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0)) {
+	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0, 0)) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/wpa_supplicant/hidl/1.2/sta_iface.cpp b/wpa_supplicant/hidl/1.2/sta_iface.cpp
index 8c5178e..1ca440e 100644
--- a/wpa_supplicant/hidl/1.2/sta_iface.cpp
+++ b/wpa_supplicant/hidl/1.2/sta_iface.cpp
@@ -925,7 +925,7 @@
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
 	const uint8_t *bssid_addr =
 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
-	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0)) {
+	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1160,7 +1160,7 @@
 		bootstrap_id_str = std::to_string(bootstrap_id);
 	}
 
-	if (wpas_dpp_bootstrap_remove(wpa_s, bootstrap_id_str.c_str()) >= 0) {
+	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
 		return {SupplicantStatusCode::SUCCESS, ""};
 	}
 #endif
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 00919d1..e96ea65 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -260,12 +260,14 @@
 
 static const u8 * auth_get_psk(void *ctx, const u8 *addr,
 			       const u8 *p2p_dev_addr, const u8 *prev_psk,
-			       size_t *psk_len)
+			       size_t *psk_len, int *vlan_id)
 {
 	struct ibss_rsn *ibss_rsn = ctx;
 
 	if (psk_len)
 		*psk_len = PMK_LEN;
+	if (vlan_id)
+		*vlan_id = 0;
 	wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
 		   __func__, MAC2STR(addr), prev_psk);
 	if (prev_psk)
@@ -457,7 +459,7 @@
 	}
 
 	/* TODO: get peer RSN IE with Probe Request */
-	if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth,
+	if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, 0,
 				(u8 *) "\x30\x14\x01\x00"
 				"\x00\x0f\xac\x04"
 				"\x01\x00\x00\x0f\xac\x04"
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index e08c2fd..51a8a02 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -28,9 +28,9 @@
 	       "s"
 #endif /* CONFIG_DEBUG_SYSLOG */
 	       "t"
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 	       "u"
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 	       "vW] [-P<pid file>] "
 	       "[-g<global ctrl>] \\\n"
 	       "        [-G<group>] \\\n"
@@ -98,9 +98,9 @@
 	       "  -T = record to Linux tracing in addition to logging\n"
 	       "       (records all messages regardless of debug verbosity)\n"
 #endif /* CONFIG_DEBUG_LINUX_TRACING */
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 	       "  -u = enable DBus control interface\n"
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 	       "  -v = show version\n"
 	       "  -W = wait for a control interface monitor before starting\n");
 
@@ -295,11 +295,11 @@
 		case 't':
 			params.wpa_debug_timestamp++;
 			break;
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 		case 'u':
 			params.dbus_ctrl_interface = 1;
 			break;
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 		case 'v':
 			printf("%s\n", wpa_supplicant_version);
 			exitcode = 0;
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index bd5020a..43b1fa7 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -98,6 +98,13 @@
 }
 
 
+static void wpas_mbo_non_pref_chan_attr_hdr(struct wpabuf *mbo, size_t size)
+{
+	wpabuf_put_u8(mbo, MBO_ATTR_ID_NON_PREF_CHAN_REPORT);
+	wpabuf_put_u8(mbo, size); /* Length */
+}
+
+
 static void wpas_mbo_non_pref_chan_attr(struct wpa_supplicant *wpa_s,
 					struct wpabuf *mbo, u8 start, u8 end)
 {
@@ -106,9 +113,7 @@
 	if (size + 2 > wpabuf_tailroom(mbo))
 		return;
 
-	wpabuf_put_u8(mbo, MBO_ATTR_ID_NON_PREF_CHAN_REPORT);
-	wpabuf_put_u8(mbo, size); /* Length */
-
+	wpas_mbo_non_pref_chan_attr_hdr(mbo, size);
 	wpas_mbo_non_pref_chan_attr_body(wpa_s, mbo, start, end);
 }
 
@@ -145,6 +150,8 @@
 	if (!wpa_s->non_pref_chan || !wpa_s->non_pref_chan_num) {
 		if (subelement)
 			wpas_mbo_non_pref_chan_subelem_hdr(mbo, 4);
+		else
+			wpas_mbo_non_pref_chan_attr_hdr(mbo, 0);
 		return;
 	}
 	start_pref = &wpa_s->non_pref_chan[0];
@@ -268,6 +275,7 @@
 	wpas_mbo_non_pref_chan_attrs(wpa_s, buf, 1);
 	wpas_mbo_send_wnm_notification(wpa_s, wpabuf_head_u8(buf),
 				       wpabuf_len(buf));
+	wpas_update_mbo_connect_params(wpa_s);
 	wpabuf_free(buf);
 }
 
@@ -293,10 +301,10 @@
 	const struct wpa_mbo_non_pref_channel *a = _a, *b = _b;
 
 	if (a->oper_class != b->oper_class)
-		return a->oper_class - b->oper_class;
+		return (int) a->oper_class - (int) b->oper_class;
 	if (a->reason != b->reason)
-		return a->reason - b->reason;
-	return a->preference - b->preference;
+		return (int) a->reason - (int) b->reason;
+	return (int) a->preference - (int) b->preference;
 }
 
 
@@ -558,6 +566,7 @@
 
 	wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7);
 	wpa_supplicant_set_default_scan_ies(wpa_s);
+	wpas_update_mbo_connect_params(wpa_s);
 }
 
 
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index e9457f0..9260021 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -197,7 +197,7 @@
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
 	int ret;
 
-	if (!params || !ssid) {
+	if (!params || !ssid || !ifmsh) {
 		wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
 			   __func__);
 		return -1;
@@ -217,13 +217,11 @@
 		wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
 	}
 
-	if (ifmsh) {
-		params->ies = ifmsh->mconf->rsn_ie;
-		params->ie_len = ifmsh->mconf->rsn_ie_len;
-		params->basic_rates = ifmsh->basic_rates;
-		params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
-		params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
-	}
+	params->ies = ifmsh->mconf->rsn_ie;
+	params->ie_len = ifmsh->mconf->rsn_ie_len;
+	params->basic_rates = ifmsh->basic_rates;
+	params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
+	params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
 
 	wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
 		wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 04ac747..4b8d6c4 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -76,7 +76,7 @@
 
 static const u8 *auth_get_psk(void *ctx, const u8 *addr,
 			      const u8 *p2p_dev_addr, const u8 *prev_psk,
-			      size_t *psk_len)
+			      size_t *psk_len, int *vlan_id)
 {
 	struct mesh_rsn *mesh_rsn = ctx;
 	struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
@@ -84,6 +84,8 @@
 
 	if (psk_len)
 		*psk_len = PMK_LEN;
+	if (vlan_id)
+		*vlan_id = 0;
 	wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
 		   __func__, MAC2STR(addr), prev_psk);
 
@@ -641,7 +643,7 @@
 	size_t crypt_len;
 	const u8 *aad[] = { sta->addr, wpa_s->own_addr, cat };
 	const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
-				   (elems->mic - 2) - cat };
+				   elems->mic ? (elems->mic - 2) - cat : 0 };
 	size_t key_len;
 
 	if (!sta->sae) {
@@ -655,7 +657,9 @@
 		mesh_rsn_auth_sae_sta(wpa_s, sta);
 	}
 
-	if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) {
+	if (chosen_pmk &&
+	    (!sta->sae ||
+	     os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN) != 0)) {
 		wpa_msg(wpa_s, MSG_DEBUG,
 			"Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
 		return -1;
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 4df1343..bd4b8ae 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -14,7 +14,6 @@
 #include "wpa_supplicant_i.h"
 #include "wps_supplicant.h"
 #include "dbus/dbus_common.h"
-#include "dbus/dbus_old.h"
 #include "dbus/dbus_new.h"
 #include "rsn_supp/wpa.h"
 #include "fst/fst.h"
@@ -27,13 +26,13 @@
 
 int wpas_notify_supplicant_initialized(struct wpa_global *global)
 {
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 	if (global->params.dbus_ctrl_interface) {
 		global->dbus = wpas_dbus_init(global);
 		if (global->dbus == NULL)
 			return -1;
 	}
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
 #ifdef CONFIG_HIDL
 	global->hidl = wpas_hidl_init(global);
@@ -47,10 +46,10 @@
 
 void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
 {
-#ifdef CONFIG_DBUS
+#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 	if (global->dbus)
 		wpas_dbus_deinit(global->dbus);
-#endif /* CONFIG_DBUS */
+#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
 #ifdef CONFIG_HIDL
 	if (global->hidl)
@@ -61,34 +60,30 @@
 
 int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
 {
-	if (!wpa_s->p2p_mgmt) {
-		if (wpas_dbus_register_iface(wpa_s))
-			return -1;
-
-		if (wpas_dbus_register_interface(wpa_s))
-			return -1;
-	}
+	if (wpa_s->p2p_mgmt)
+		return 0;
 
 	/* HIDL interface wants to keep track of the P2P mgmt iface. */
 	if (wpas_hidl_register_interface(wpa_s))
 		return -1;
 
+	if (wpas_dbus_register_interface(wpa_s))
+		return -1;
+
 	return 0;
 }
 
 
 void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s)
 {
-	if (!wpa_s->p2p_mgmt) {
-		/* unregister interface in old DBus ctrl iface */
-		wpas_dbus_unregister_iface(wpa_s);
-
-		/* unregister interface in new DBus ctrl iface */
-		wpas_dbus_unregister_interface(wpa_s);
-	}
+	if (wpa_s->p2p_mgmt)
+		return;
 
 	/* HIDL interface wants to keep track of the P2P mgmt iface. */
 	wpas_hidl_unregister_interface(wpa_s);
+
+	/* unregister interface in new DBus ctrl iface */
+	wpas_dbus_unregister_interface(wpa_s);
 }
 
 
@@ -99,10 +94,6 @@
 	if (wpa_s->p2p_mgmt)
 		return;
 
-	/* notify the old DBus API */
-	wpa_supplicant_dbus_notify_state_change(wpa_s, new_state,
-						old_state);
-
 	/* notify the new DBus API */
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
 
@@ -288,9 +279,6 @@
 	if (wpa_s->p2p_mgmt)
 		return;
 
-	/* notify the old DBus API */
-	wpa_supplicant_dbus_notify_scanning(wpa_s);
-
 	/* notify the new DBus API */
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SCANNING);
 }
@@ -310,9 +298,6 @@
 	if (wpa_s->p2p_mgmt)
 		return;
 
-	/* notify the old DBus API */
-	wpa_supplicant_dbus_notify_scan_results(wpa_s);
-
 	wpas_wps_notify_scan_results(wpa_s);
 }
 
@@ -324,8 +309,6 @@
 		return;
 
 #ifdef CONFIG_WPS
-	/* notify the old DBus API */
-	wpa_supplicant_dbus_notify_wps_cred(wpa_s, cred);
 	/* notify the new DBus API */
 	wpas_dbus_signal_wps_cred(wpa_s, cred);
 #endif /* CONFIG_WPS */
@@ -909,9 +892,6 @@
 				"depth=%d %s", depth, altsubject[i]);
 	}
 
-	/* notify the old DBus API */
-	wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
-						 cert_hash, cert);
 	/* notify the new DBus API */
 	wpas_dbus_signal_certification(wpa_s, depth, subject, altsubject,
 				       num_altsubject, cert_hash, cert);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 78011c6..562caad 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -980,6 +980,7 @@
 	os_free(wpa_s->p2p_group_common_freqs);
 	wpa_s->p2p_group_common_freqs = NULL;
 	wpa_s->p2p_group_common_freqs_num = 0;
+	wpa_s->p2p_go_do_acs = 0;
 
 	wpa_s->waiting_presence_resp = 0;
 
@@ -1584,20 +1585,27 @@
 
 static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
 			    const u8 *src, const u8 *bssid, const u8 *buf,
-			    size_t len, unsigned int wait_time)
+			    size_t len, unsigned int wait_time, int *scheduled)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	int listen_freq = -1, send_freq = -1;
 
+	if (scheduled)
+		*scheduled = 0;
 	if (wpa_s->p2p_listen_work)
 		listen_freq = wpa_s->p2p_listen_work->freq;
 	if (wpa_s->p2p_send_action_work)
 		send_freq = wpa_s->p2p_send_action_work->freq;
 	if (listen_freq != (int) freq && send_freq != (int) freq) {
-		wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d)",
-			   listen_freq, send_freq);
-		return wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
-					     len, wait_time);
+		int res;
+
+		wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d freq=%u)",
+			   listen_freq, send_freq, freq);
+		res = wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
+					    len, wait_time);
+		if (res == 0 && scheduled)
+			*scheduled = 1;
+		return res;
 	}
 
 	wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");
@@ -1649,7 +1657,7 @@
 	wpa_supplicant_ap_deinit(wpa_s);
 	wpas_copy_go_neg_results(wpa_s, res);
 	if (res->wps_method == WPS_PBC) {
-		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
+		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
 #ifdef CONFIG_WPS_NFC
 	} else if (res->wps_method == WPS_NFC) {
 		wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 727c49a..7abb028 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - Scanning
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -1993,7 +1993,8 @@
 	/* if SNR is close, decide by max rate or frequency band */
 	if (snr_a && snr_b && abs(snr_b - snr_a) < 7) {
 		if (wa->est_throughput != wb->est_throughput)
-			return wb->est_throughput - wa->est_throughput;
+			return (int) wb->est_throughput -
+				(int) wa->est_throughput;
 	}
 	if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
 	    (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index ba22a93..4bb5f3a 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -16,6 +16,7 @@
 #include "eapol_supp/eapol_supp_sm.h"
 #include "common/wpa_common.h"
 #include "common/sae.h"
+#include "common/dpp.h"
 #include "rsn_supp/wpa.h"
 #include "rsn_supp/pmksa_cache.h"
 #include "config.h"
@@ -57,7 +58,7 @@
 static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
 {
 	int *groups = wpa_s->conf->sae_groups;
-	int default_groups[] = { 19, 20, 21, 25, 26, 0 };
+	int default_groups[] = { 19, 20, 21, 0 };
 
 	if (!groups || groups[0] <= 0)
 		groups = default_groups;
@@ -84,7 +85,8 @@
 
 static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
 						 struct wpa_ssid *ssid,
-						 const u8 *bssid, int external)
+						 const u8 *bssid, int external,
+						 int reuse)
 {
 	struct wpabuf *buf;
 	size_t len;
@@ -96,8 +98,10 @@
 		buf = wpabuf_alloc(4 + wpabuf_len(wpa_s->sae_commit_override));
 		if (!buf)
 			return NULL;
-		wpabuf_put_le16(buf, 1); /* Transaction seq# */
-		wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+		if (!external) {
+			wpabuf_put_le16(buf, 1); /* Transaction seq# */
+			wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+		}
 		wpabuf_put_buf(buf, wpa_s->sae_commit_override);
 		return buf;
 	}
@@ -111,6 +115,12 @@
 		return NULL;
 	}
 
+	if (reuse && wpa_s->sme.sae.tmp &&
+	    os_memcmp(bssid, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) {
+		wpa_printf(MSG_DEBUG,
+			   "SAE: Reuse previously generated PWE on a retry with the same AP");
+		goto reuse_data;
+	}
 	if (sme_set_sae_group(wpa_s) < 0) {
 		wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
 		return NULL;
@@ -123,7 +133,10 @@
 		wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
 		return NULL;
 	}
+	if (wpa_s->sme.sae.tmp)
+		os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN);
 
+reuse_data:
 	len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0;
 	if (ssid->sae_password_id)
 		len += 4 + os_strlen(ssid->sae_password_id);
@@ -303,6 +316,12 @@
 		if (!rsn) {
 			wpa_dbg(wpa_s, MSG_DEBUG,
 				"SAE enabled, but target BSS does not advertise RSN");
+#ifdef CONFIG_DPP
+		} else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
+			   (ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
+			   (ied.key_mgmt & WPA_KEY_MGMT_DPP)) {
+			wpa_dbg(wpa_s, MSG_DEBUG, "Prefer DPP over SAE when both are enabled");
+#endif /* CONFIG_DPP */
 		} else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
 			   wpa_key_mgmt_sae(ied.key_mgmt)) {
 			wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg");
@@ -435,13 +454,14 @@
 	if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
 		md = ie + 2;
 	wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
+	if (md && (!wpa_key_mgmt_ft(ssid->key_mgmt) ||
+		   !wpa_key_mgmt_ft(wpa_s->key_mgmt)))
+		md = NULL;
 	if (md) {
 		/* Prepare for the next transition */
 		wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
 	}
 
-	if (md && !wpa_key_mgmt_ft(ssid->key_mgmt))
-		md = NULL;
 	if (md) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
 			md[0], md[1]);
@@ -620,7 +640,10 @@
 #ifdef CONFIG_SAE
 	if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE &&
 	    pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0,
-				    NULL, WPA_KEY_MGMT_SAE) == 0) {
+				    NULL,
+				    wpa_s->key_mgmt == WPA_KEY_MGMT_FT_SAE ?
+				    WPA_KEY_MGMT_FT_SAE :
+				    WPA_KEY_MGMT_SAE) == 0) {
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication");
 		wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
@@ -631,7 +654,8 @@
 	if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
 		if (start)
 			resp = sme_auth_build_sae_commit(wpa_s, ssid,
-							 bss->bssid, 0);
+							 bss->bssid, 0,
+							 start == 2);
 		else
 			resp = sme_auth_build_sae_confirm(wpa_s, 0);
 		if (resp == NULL) {
@@ -914,7 +938,7 @@
 {
 	struct wpabuf *resp, *buf;
 
-	resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1);
+	resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0);
 	if (!resp)
 		return;
 
@@ -961,7 +985,7 @@
 		if (!wpas_network_disabled(wpa_s, ssid) &&
 		    ssid_str_len == ssid->ssid_len &&
 		    os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
-		    (ssid->key_mgmt & WPA_KEY_MGMT_SAE))
+		    (ssid->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE)))
 			break;
 	}
 	if (ssid)
@@ -1037,7 +1061,7 @@
 	    status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
 	    wpa_s->sme.sae.state == SAE_COMMITTED &&
 	    (external || wpa_s->current_bss) && wpa_s->current_ssid) {
-		int default_groups[] = { 19, 20, 21, 25, 26, 0 };
+		int default_groups[] = { 19, 20, 21, 0 };
 		u16 group;
 
 		groups = wpa_s->conf->sae_groups;
@@ -1065,7 +1089,7 @@
 							 len - sizeof(le16));
 		if (!external)
 			sme_send_authentication(wpa_s, wpa_s->current_bss,
-						wpa_s->current_ssid, 1);
+						wpa_s->current_ssid, 2);
 		else
 			sme_external_auth_send_sae_commit(
 				wpa_s, wpa_s->sme.ext_auth.bssid,
@@ -1554,6 +1578,36 @@
 	}
 #endif /* CONFIG_OWE */
 
+#ifdef CONFIG_DPP2
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && wpa_s->current_ssid &&
+	    wpa_s->current_ssid->dpp_netaccesskey) {
+		struct wpa_ssid *ssid = wpa_s->current_ssid;
+
+		dpp_pfs_free(wpa_s->dpp_pfs);
+		wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
+					      ssid->dpp_netaccesskey_len);
+		if (!wpa_s->dpp_pfs) {
+			wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
+			/* Try to continue without PFS */
+			goto pfs_fail;
+		}
+		if (wpa_s->sme.assoc_req_ie_len +
+		    wpabuf_len(wpa_s->dpp_pfs->ie) >
+		    sizeof(wpa_s->sme.assoc_req_ie)) {
+			wpa_printf(MSG_ERROR,
+				   "DPP: Not enough buffer room for own Association Request frame elements");
+			dpp_pfs_free(wpa_s->dpp_pfs);
+			wpa_s->dpp_pfs = NULL;
+			goto pfs_fail;
+		}
+		os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
+			  wpabuf_head(wpa_s->dpp_pfs->ie),
+			  wpabuf_len(wpa_s->dpp_pfs->ie));
+		wpa_s->sme.assoc_req_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
+	}
+pfs_fail:
+#endif /* CONFIG_DPP2 */
+
 	if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
 		size_t multi_ap_ie_len;
 
diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in
index bc5d49a..75a37a8 100644
--- a/wpa_supplicant/systemd/wpa_supplicant.service.in
+++ b/wpa_supplicant/systemd/wpa_supplicant.service.in
@@ -5,9 +5,9 @@
 
 [Service]
 Type=dbus
-BusName=@DBUS_INTERFACE@
+BusName=fi.w1.wpa_supplicant1
 ExecStart=@BINDIR@/wpa_supplicant -u
 
 [Install]
 WantedBy=multi-user.target
-Alias=dbus-@DBUS_INTERFACE@.service
+Alias=dbus-fi.w1.wpa_supplicant1.service
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 9881021..695fcbe 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1411,9 +1411,11 @@
 	"eap", "identity", "anonymous_identity", "password", "ca_cert",
 	"ca_path", "client_cert", "private_key", "private_key_passwd",
 	"dh_file", "subject_match", "altsubject_match",
+	"check_cert_subject",
 	"domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
 	"client_cert2", "private_key2", "private_key2_passwd",
 	"dh_file2", "subject_match2", "altsubject_match2",
+	"check_cert_subject2",
 	"domain_suffix_match2", "domain_match2", "phase1", "phase2",
 	"pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
 	"pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index f3e7d01..0f7b85d 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -39,6 +39,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/hw_features_common.h"
 #include "common/gas_server.h"
+#include "common/dpp.h"
 #include "p2p/p2p.h"
 #include "fst/fst.h"
 #include "blacklist.h"
@@ -673,6 +674,8 @@
 
 #ifdef CONFIG_DPP
 	wpas_dpp_deinit(wpa_s);
+	dpp_global_deinit(wpa_s->dpp);
+	wpa_s->dpp = NULL;
 #endif /* CONFIG_DPP */
 }
 
@@ -1190,6 +1193,18 @@
 }
 
 
+static int matching_ciphers(struct wpa_ssid *ssid, struct wpa_ie_data *ie,
+			    int freq)
+{
+	if (!ie->has_group)
+		ie->group_cipher = wpa_default_rsn_cipher(freq);
+	if (!ie->has_pairwise)
+		ie->pairwise_cipher = wpa_default_rsn_cipher(freq);
+	return (ie->group_cipher & ssid->group_cipher) &&
+		(ie->pairwise_cipher & ssid->pairwise_cipher);
+}
+
+
 /**
  * wpa_supplicant_set_suites - Set authentication and encryption parameters
  * @wpa_s: Pointer to wpa_supplicant data
@@ -1221,8 +1236,7 @@
 
 	if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
 	    wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
-	    (ie.group_cipher & ssid->group_cipher) &&
-	    (ie.pairwise_cipher & ssid->pairwise_cipher) &&
+	    matching_ciphers(ssid, &ie, bss->freq) &&
 	    (ie.key_mgmt & ssid->key_mgmt)) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
 		proto = WPA_PROTO_RSN;
@@ -1362,6 +1376,9 @@
 	wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
 #else /* CONFIG_NO_WPA */
 	sel = ie.group_cipher & ssid->group_cipher;
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP group 0x%x network profile group 0x%x; available group 0x%x",
+		ie.group_cipher, ssid->group_cipher, sel);
 	wpa_s->group_cipher = wpa_pick_group_cipher(sel);
 	if (wpa_s->group_cipher < 0) {
 		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
@@ -1372,6 +1389,9 @@
 		wpa_cipher_txt(wpa_s->group_cipher));
 
 	sel = ie.pairwise_cipher & ssid->pairwise_cipher;
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP pairwise 0x%x network profile pairwise 0x%x; available pairwise 0x%x",
+		ie.pairwise_cipher, ssid->pairwise_cipher, sel);
 	wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
 	if (wpa_s->pairwise_cipher < 0) {
 		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
@@ -1383,11 +1403,29 @@
 #endif /* CONFIG_NO_WPA */
 
 	sel = ie.key_mgmt & ssid->key_mgmt;
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP key_mgmt 0x%x network profile key_mgmt 0x%x; available key_mgmt 0x%x",
+		ie.key_mgmt, ssid->key_mgmt, sel);
 #ifdef CONFIG_SAE
 	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
 		sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
 #endif /* CONFIG_SAE */
 	if (0) {
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SHA384
+	} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
+		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: using KEY_MGMT FT/802.1X-SHA384");
+		if (pmksa_cache_get_current(wpa_s->wpa)) {
+			/* PMKSA caching with FT is not fully functional, so
+			 * disable the case for now. */
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"WPA: Disable PMKSA caching for FT/802.1X connection");
+			pmksa_cache_clear_current(wpa_s->wpa);
+		}
+#endif /* CONFIG_SHA384 */
+#endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_SUITEB192
 	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
@@ -1417,19 +1455,6 @@
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA256");
 #endif /* CONFIG_FILS */
 #ifdef CONFIG_IEEE80211R
-#ifdef CONFIG_SHA384
-	} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
-		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
-		wpa_dbg(wpa_s, MSG_DEBUG,
-			"WPA: using KEY_MGMT FT/802.1X-SHA384");
-		if (pmksa_cache_get_current(wpa_s->wpa)) {
-			/* PMKSA caching with FT is not fully functional, so
-			 * disable the case for now. */
-			wpa_dbg(wpa_s, MSG_DEBUG,
-				"WPA: Disable PMKSA caching for FT/802.1X connection");
-			pmksa_cache_clear_current(wpa_s->wpa);
-		}
-#endif /* CONFIG_SHA384 */
 	} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
@@ -1440,18 +1465,25 @@
 				"WPA: Disable PMKSA caching for FT/802.1X connection");
 			pmksa_cache_clear_current(wpa_s->wpa);
 		}
+#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_DPP
+	} else if (sel & WPA_KEY_MGMT_DPP) {
+		wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
+		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
+#endif /* CONFIG_DPP */
+#ifdef CONFIG_SAE
+	} else if (sel & WPA_KEY_MGMT_FT_SAE) {
+		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
+		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
+	} else if (sel & WPA_KEY_MGMT_SAE) {
+		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
+		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_IEEE80211R
 	} else if (sel & WPA_KEY_MGMT_FT_PSK) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
 #endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_SAE
-	} else if (sel & WPA_KEY_MGMT_SAE) {
-		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
-		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
-	} else if (sel & WPA_KEY_MGMT_FT_SAE) {
-		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
-		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
-#endif /* CONFIG_SAE */
 #ifdef CONFIG_IEEE80211W
 	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
@@ -1481,11 +1513,6 @@
 		wpa_s->key_mgmt = WPA_KEY_MGMT_OWE;
 		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT OWE");
 #endif /* CONFIG_OWE */
-#ifdef CONFIG_DPP
-	} else if (sel & WPA_KEY_MGMT_DPP) {
-		wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
-		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
-#endif /* CONFIG_DPP */
 	} else {
 		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
 			"authenticated key management type");
@@ -1504,6 +1531,9 @@
 	if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
 	    !(ie.capabilities & WPA_CAPABILITY_MFPC))
 		sel = 0;
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP mgmt_group_cipher 0x%x network profile mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
+		ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
 	if (sel & WPA_CIPHER_AES_128_CMAC) {
 		wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
 		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
@@ -1538,7 +1568,13 @@
 		return -1;
 	}
 
-	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
+	if (0) {
+#ifdef CONFIG_DPP
+	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
+		/* Use PMK from DPP network introduction (PMKSA entry) */
+		wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
+#endif /* CONFIG_DPP */
+	} else if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
 		int psk_set = 0;
 		int sae_only;
 
@@ -2811,11 +2847,33 @@
 			os_memcpy(wpa_ie + wpa_ie_len,
 				  wpabuf_head(owe_ie), wpabuf_len(owe_ie));
 			wpa_ie_len += wpabuf_len(owe_ie);
-			wpabuf_free(owe_ie);
 		}
+		wpabuf_free(owe_ie);
 	}
 #endif /* CONFIG_OWE */
 
+#ifdef CONFIG_DPP2
+	if (wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP &&
+	    ssid->dpp_netaccesskey) {
+		dpp_pfs_free(wpa_s->dpp_pfs);
+		wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
+					      ssid->dpp_netaccesskey_len);
+		if (!wpa_s->dpp_pfs) {
+			wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
+			/* Try to continue without PFS */
+			goto pfs_fail;
+		}
+		if (wpabuf_len(wpa_s->dpp_pfs->ie) <=
+		    max_wpa_ie_len - wpa_ie_len) {
+			os_memcpy(wpa_ie + wpa_ie_len,
+				  wpabuf_head(wpa_s->dpp_pfs->ie),
+				  wpabuf_len(wpa_s->dpp_pfs->ie));
+			wpa_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
+		}
+	}
+pfs_fail:
+#endif /* CONFIG_DPP2 */
+
 #ifdef CONFIG_IEEE80211R
 	/*
 	 * Add MDIE under these conditions: the network profile allows FT,
@@ -2902,6 +2960,34 @@
 #endif /* CONFIG_FILS && IEEE8021X_EAPOL */
 
 
+#ifdef CONFIG_MBO
+void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_driver_associate_params params;
+	u8 *wpa_ie;
+
+	/*
+	 * Update MBO connect params only in case of change of MBO attributes
+	 * when connected, if the AP support MBO.
+	 */
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid ||
+	    !wpa_s->current_bss ||
+	    !wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE))
+		return;
+
+	os_memset(&params, 0, sizeof(params));
+	wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
+					 wpa_s->current_ssid, &params, NULL);
+	if (!wpa_ie)
+		return;
+
+	wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_ASSOC_IES);
+	os_free(wpa_ie);
+}
+#endif /* CONFIG_MBO */
+
+
 static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 {
 	struct wpa_connect_work *cwork = work->ctx;
@@ -3943,7 +4029,9 @@
 	while (entry) {
 		if (!wpas_network_disabled(wpa_s, entry) &&
 		    ((ssid_len == entry->ssid_len &&
-		      os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
+		      (!entry->ssid ||
+		       os_memcmp(ssid, entry->ssid, ssid_len) == 0)) ||
+		     wired) &&
 		    (!entry->bssid_set ||
 		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
 			return entry;
@@ -6685,6 +6773,9 @@
 	 * TODO: if more than one possible AP is available in scan results,
 	 * could try the other ones before requesting a new scan.
 	 */
+
+	/* speed up the connection attempt with normal scan */
+	wpa_s->normal_scans = 0;
 	wpa_supplicant_req_scan(wpa_s, timeout / 1000,
 				1000 * (timeout % 1000));
 }
@@ -7105,6 +7196,8 @@
 	wpa_supplicant_cancel_scan(wpa_s);
 	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 	eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+	radio_remove_works(wpa_s, "connect", 0);
+	radio_remove_works(wpa_s, "sme-connect", 0);
 }
 
 
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 1bd43b2..a66253f 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -282,6 +282,14 @@
 #	to external program(s)
 #wps_cred_processing=0
 
+# Whether to enable SAE (WPA3-Personal transition mode) automatically for
+# WPA2-PSK credentials received using WPS.
+# 0 = only add the explicitly listed WPA2-PSK configuration (default)
+# 1 = add both the WPA2-PSK and SAE configuration and enable PMF so that the
+#     station gets configured in WPA3-Personal transition mode (supports both
+#     WPA2-Personal (PSK) and WPA3-Personal (SAE) APs).
+#wps_cred_add_sae=0
+
 # Vendor attribute in WPS M1, e.g., Windows 7 Vertical Pairing
 # The vendor attribute contents to be added in M1 (hex string)
 #wps_vendor_ext_m1=000137100100020001
@@ -377,11 +385,16 @@
 
 # Enabled SAE finite cyclic groups in preference order
 # By default (if this parameter is not set), the mandatory group 19 (ECC group
-# defined over a 256-bit prime order field) is preferred, but other groups are
-# also enabled. If this parameter is set, the groups will be tried in the
-# indicated order. The group values are listed in the IANA registry:
+# defined over a 256-bit prime order field, NIST P-256) is preferred and groups
+# 20 (NIST P-384) and 21 (NIST P-521) are also enabled. If this parameter is
+# set, the groups will be tried in the indicated order.
+# The group values are listed in the IANA registry:
 # http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-9
-#sae_groups=21 20 19 26 25
+# Note that groups 1, 2, 5, 22, 23, and 24 should not be used in production
+# purposes due limited security (see RFC 8247). Groups that are not as strong as
+# group 19 (ECC, NIST P-256) are unlikely to be useful for production use cases
+# since all implementations are required to support group 19.
+#sae_groups=19 20 21
 
 # Default value for DTIM period (if not overridden in network block)
 #dtim_period=2
@@ -1167,6 +1180,12 @@
 #	certificate may include additional sub-level labels in addition to the
 #	required labels.
 #
+#	More than one match string can be provided by using semicolons to
+#	separate the strings (e.g., example.org;example.com). When multiple
+#	strings are specified, a match with any one of the values is considered
+#	a sufficient match for the certificate, i.e., the conditions are ORed
+#	together.
+#
 #	For example, domain_suffix_match=example.com would match
 #	test.example.com but would not match test-example.com.
 # domain_match: Constraint for server domain name
@@ -1179,6 +1198,12 @@
 #	no subdomains or wildcard matches are allowed. Case-insensitive
 #	comparison is used, so "Example.com" matches "example.com", but would
 #	not match "test.Example.com".
+#
+#	More than one match string can be provided by using semicolons to
+#	separate the strings (e.g., example.org;example.com). When multiple
+#	strings are specified, a match with any one of the values is considered
+#	a sufficient match for the certificate, i.e., the conditions are ORed
+#	together.
 # phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters
 #	(string with field-value pairs, e.g., "peapver=0" or
 #	"peapver=1 peaplabel=1")
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 9cb4ad3..a97353f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -504,9 +504,6 @@
 #ifdef CONFIG_MATCH_IFACE
 	int matched;
 #endif /* CONFIG_MATCH_IFACE */
-#ifdef CONFIG_CTRL_IFACE_DBUS
-	char *dbus_path;
-#endif /* CONFIG_CTRL_IFACE_DBUS */
 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
 	char *dbus_new_path;
 	char *dbus_groupobj_path;
@@ -751,6 +748,10 @@
 	unsigned int wnmsleep_used:1;
 	unsigned int owe_transition_select:1;
 	unsigned int owe_transition_search:1;
+	unsigned int connection_set:1;
+	unsigned int connection_ht:1;
+	unsigned int connection_vht:1;
+	unsigned int connection_he:1;
 
 	struct os_reltime last_mac_addr_change;
 	int last_mac_addr_style;
@@ -1208,9 +1209,7 @@
 	int last_auth_timeout_sec;
 
 #ifdef CONFIG_DPP
-	struct dl_list dpp_bootstrap; /* struct dpp_bootstrap_info */
-	struct dl_list dpp_configurator; /* struct dpp_configurator */
-	int dpp_init_done;
+	struct dpp_global *dpp;
 	struct dpp_authentication *dpp_auth;
 	struct wpa_radio_work *dpp_listen_work;
 	unsigned int dpp_pending_listen_freq;
@@ -1237,6 +1236,9 @@
 	unsigned int dpp_resp_wait_time;
 	unsigned int dpp_resp_max_tries;
 	unsigned int dpp_resp_retry_time;
+#ifdef CONFIG_DPP2
+	struct dpp_pfs *dpp_pfs;
+#endif /* CONFIG_DPP2 */
 #ifdef CONFIG_TESTING_OPTIONS
 	char *dpp_config_obj_override;
 	char *dpp_discovery_override;
@@ -1402,6 +1404,7 @@
 void mbo_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
 			    struct wpa_bss *bss, const u8 *sa,
 			    const u8 *data, size_t slen);
+void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s);
 
 /* op_classes.c */
 enum chan_allowed {
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 4fffd80..2950763 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -530,11 +530,18 @@
 	case WPS_AUTH_WPA2PSK:
 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
 		ssid->key_mgmt = WPA_KEY_MGMT_PSK;
+		if (wpa_s->conf->wps_cred_add_sae &&
+		    cred->key_len != 2 * PMK_LEN) {
+			ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
+#ifdef CONFIG_IEEE80211W
+			ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
+#endif /* CONFIG_IEEE80211W */
+		}
 		ssid->proto = WPA_PROTO_RSN;
 		break;
 	}
 
-	if (ssid->key_mgmt == WPA_KEY_MGMT_PSK) {
+	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
 		if (cred->key_len == 2 * PMK_LEN) {
 			if (hexstr2bin((const char *) cred->key, ssid->psk,
 				       PMK_LEN)) {
@@ -1137,9 +1144,10 @@
 
 
 int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
-		       int p2p_group)
+		       int p2p_group, int multi_ap_backhaul_sta)
 {
 	struct wpa_ssid *ssid;
+	char phase1[32];
 
 #ifdef CONFIG_AP
 	if (wpa_s->ap_iface) {
@@ -1177,10 +1185,14 @@
 		}
 	}
 #endif /* CONFIG_P2P */
-	if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
+	os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
+		    multi_ap_backhaul_sta ? " multi_ap=1" : "");
+	if (wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
 		return -1;
 	if (wpa_s->wps_fragment_size)
 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
+	if (multi_ap_backhaul_sta)
+		ssid->multi_ap_backhaul_sta = 1;
 	wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
 			       wpa_s, NULL);
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index eb1615a..3a99f2c 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -30,7 +30,7 @@
 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
 enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
 int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
-		       int p2p_group);
+		       int p2p_group, int multi_ap_backhaul_sta);
 int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
 		       const char *pin, int p2p_group, u16 dev_pw_id);
 void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);