Cumulative patch from comit b97a54108732b8b5048f86388bed305df21ea8e5

b97a541 IBSS: Fix a memory leak on RSN error path
5f040be Move disconnect command handling to a common place
478441b OpenSSL: Fix OpenSSL 1.1.0 compatibility functions
6c33ca9 Add group_rekey parameter for IBSS
79931ef hostapd: Fix parsing the das_client option
4fe726e nl80211: Do not switch interface to station mode when using mesh
8468189 Do not include NAS-Port attribute with AID 0
86a318f atheros: Accept Public Action frames sent to Wildcard BSSID
e07adb7 Fix EAP state machine reset with offloaded roaming and authorization
6fe3b9d QCA vendor command to get hardware capabilities
dc24a36 Define an attribute QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER
42d30e9 Add a require_message_authenticator configuration option
715ad33 roboswitch: Add support for BCM63xx
a2072a2 utils: os_unix: Use access() for checking file existence
cfe0a01 mka: Fix use after free
d68b73c mka: Add check for body length when decoding peers
ad19e71 mka: Avoid reading past the end of mka_body_handler
65b4773 mka: Return u8 from get_mka_param_body_type()
ac285c0 mka: Add error handling around ieee802_1x_kay_move_live_peer()
90bff0e mka: Avoid inconsistent state in ieee802_1x_kay_move_live_peer()
1244745 mka: Fix length when encoding SAK-use
71dc789 mka: Fix memory leak in ieee802_1x_kay_create_live_peer() error path
099613e mka: Fix multiple key server election bugs
a197946 binder: Clang format the source code
fe1d077 binder: Expose an aidl interface module
b84ce65 Link to, and adjust types for, the PCSC framework included with OSX
842c5af ap: Use is_broadcast_ether_addr()
ac81b39 cli: Share a common tokenize_cmd() implementation
a6d56a3 wpa_cli: Replace str_match() with common str_starts()
980afcc cli: Share a common write_cmd() implementation
fcc84b4 cli: Share a common get_cmd_arg_num() implementation
e55df99 Share a single str_starts() implementation
23c130e Use a common license string for hostapd_cli and wpa_cli
b90c13d hostapd_cli: Completion for interface command
8b73c6a hostapd_cli: Completion for disassociate and deauthenticate
1cef253 hostapd_cli: Implement event handler
977c079 Move parts of wpa_cli to a new common file
6cad0bf hostapd_cli: Add completion for help command
0193883 hostapd_cli: Replace static usage string with print_help() function
1f927cd hostapd_cli: Add command completion support
003fe58 wpa_cli: Implement completion routine for get_capability
fed802c Define an attribute QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX
14b7612 Define vendor command to support IE based access control
4ac75cd QCA vendor command to configure GPIO pins
babf0ce Assign QCA vendor attributes for generic commands
112fdee P2P: Fix D-Bus persistent parameter in group started event
cc9985d Set default scan IEs to the driver (QCA vendor extension)
4f910f3 Fix a typo in QCA vendor attribution documentation
ab21863 Define QCA vendor config attribute to set default scan IEs to the driver
5a5638a Show disabled HT/VHT properly in AP mode STATUS command
551817a AP: Disable VHT in WEP configuration
8df4765 doc: Correct spelling mistake

Change-Id: I4341e07c85f76ead78d7217ea1c30672fa44432e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 0e08152..a8d6a7f 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -49,6 +49,12 @@
 L_CFLAGS += -mabi=aapcs-linux
 endif
 
+# C++ flags for binder interface
+L_CPPFLAGS := -std=c++11 -Wall -Werror
+# TODO: Remove these allowed warnings later.
+L_CPPFLAGS += -Wno-unused-variable -Wno-unused-parameter
+L_CPPFLAGS += -Wno-unused-private-field
+
 INCLUDES = $(LOCAL_PATH)
 INCLUDES += $(LOCAL_PATH)/src
 INCLUDES += $(LOCAL_PATH)/src/common
@@ -94,6 +100,7 @@
 OBJS_c = wpa_cli.c src/common/wpa_ctrl.c
 OBJS_c += src/utils/wpa_debug.c
 OBJS_c += src/utils/common.c
+OBJS_c += src/common/cli.c
 OBJS_d =
 OBJS_priv =
 
@@ -1349,13 +1356,8 @@
 L_CFLAGS += $(DBUS_CFLAGS)
 
 ifdef CONFIG_CTRL_IFACE_BINDER
-BINDER=y
+WPA_SUPPLICANT_USE_BINDER=y
 L_CFLAGS += -DCONFIG_BINDER -DCONFIG_CTRL_IFACE_BINDER
-OBJS += binder/binder.cpp binder/binder_manager.cpp
-OBJS += binder/supplicant.cpp binder/iface.cpp
-OBJS += binder/fi/w1/wpa_supplicant/ISupplicant.aidl
-OBJS += binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
-OBJS += binder/fi/w1/wpa_supplicant/IIface.aidl
 endif
 
 ifdef CONFIG_READLINE
@@ -1595,9 +1597,9 @@
 ifeq ($(DBUS), y)
 LOCAL_SHARED_LIBRARIES += libdbus
 endif
-ifeq ($(BINDER), y)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder frameworks/native/aidl/binder
-LOCAL_SHARED_LIBRARIES += libutils libbinder
+ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
+LOCAL_SHARED_LIBRARIES += libbinder libutils
+LOCAL_STATIC_LIBRARIES += libwpa_binder libwpa_binder_interface
 endif
 include $(BUILD_EXECUTABLE)
 
@@ -1637,3 +1639,42 @@
 LOCAL_COPY_HEADERS := src/common/wpa_ctrl.h
 LOCAL_COPY_HEADERS += src/common/qca-vendor.h
 include $(BUILD_SHARED_LIBRARY)
+
+ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
+### Binder interface library ###
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwpa_binder_interface
+LOCAL_AIDL_INCLUDES := \
+    $(LOCAL_PATH)/binder \
+    frameworks/native/aidl/binder
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/binder
+LOCAL_CPPFLAGS := $(L_CPPFLAGS)
+LOCAL_SRC_FILES := \
+    binder/binder_constants.cpp \
+    binder/fi/w1/wpa_supplicant/ISupplicant.aidl \
+    binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl \
+    binder/fi/w1/wpa_supplicant/IIface.aidl
+LOCAL_SHARED_LIBRARIES := libbinder
+include $(BUILD_STATIC_LIBRARY)
+
+### Binder service library ###
+########################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwpa_binder
+LOCAL_CPPFLAGS := $(L_CPPFLAGS)
+LOCAL_CFLAGS := $(L_CFLAGS)
+LOCAL_C_INCLUDES := $(INCLUDES)
+LOCAL_SRC_FILES := \
+    binder/binder.cpp binder/binder_manager.cpp \
+    binder/supplicant.cpp binder/iface.cpp
+LOCAL_SHARED_LIBRARIES := \
+    libbinder \
+    libutils
+LOCAL_STATIC_LIBRARIES := libwpa_binder_interface
+include $(BUILD_STATIC_LIBRARY)
+
+endif # BINDER == y
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 2e61abe..f3e86c1 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -110,6 +110,7 @@
 OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o
 OBJS_c += ../src/utils/wpa_debug.o
 OBJS_c += ../src/utils/common.o
+OBJS_c += ../src/common/cli.o
 OBJS += wmm_ac.o
 
 ifndef CONFIG_OS
@@ -930,9 +931,13 @@
 #dynamic symbol loading that is now used in pcsc_funcs.c
 #LIBS += -lwinscard
 else
+ifdef CONFIG_OSX
+LIBS += -framework PCSC
+else
 LIBS += -lpcsclite -lpthread
 endif
 endif
+endif
 
 ifdef CONFIG_SIM_SIMULATOR
 CFLAGS += -DCONFIG_SIM_SIMULATOR
diff --git a/wpa_supplicant/binder/.clang-format b/wpa_supplicant/binder/.clang-format
new file mode 100644
index 0000000..dbfdabf
--- /dev/null
+++ b/wpa_supplicant/binder/.clang-format
@@ -0,0 +1,9 @@
+BasedOnStyle: LLVM
+IndentWidth: 8
+UseTab: Always
+BreakBeforeBraces: Mozilla
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+AccessModifierOffset: -8
+AlignAfterOpenBracket: AlwaysBreak
+SortIncludes: false
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
index 28f7a2b..750e878 100644
--- a/wpa_supplicant/binder/binder.cpp
+++ b/wpa_supplicant/binder/binder.cpp
@@ -8,36 +8,35 @@
  */
 
 #include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
 
 #include "binder_manager.h"
 
 extern "C" {
-#include "utils/includes.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
 #include "binder.h"
 #include "binder_i.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
 }
 
 void wpas_binder_sock_handler(int sock, void *eloop_ctx, void *sock_ctx)
 {
-	struct wpa_global *global = (wpa_global *) eloop_ctx;
-	struct wpas_binder_priv *priv = (wpas_binder_priv *) sock_ctx;
+	struct wpa_global *global = (wpa_global *)eloop_ctx;
+	struct wpas_binder_priv *priv = (wpas_binder_priv *)sock_ctx;
 
-	wpa_printf(MSG_DEBUG, "Processing binder events on FD %d",
-		   priv->binder_fd);
+	wpa_printf(
+	    MSG_DEBUG, "Processing binder events on FD %d", priv->binder_fd);
 	android::IPCThreadState::self()->handlePolledCommands();
 }
 
-
-struct wpas_binder_priv * wpas_binder_init(struct wpa_global *global)
+struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global)
 {
 	struct wpas_binder_priv *priv;
 	wpa_supplicant_binder::BinderManager *binder_manager;
 
-	priv = (wpas_binder_priv *) os_zalloc(sizeof(*priv));
+	priv = (wpas_binder_priv *)os_zalloc(sizeof(*priv));
 	if (!priv)
 		return NULL;
 	priv->global = global;
@@ -49,8 +48,8 @@
 	if (priv->binder_fd < 0)
 		goto err;
 	/* Look for read events from the binder socket in the eloop. */
-	if (eloop_register_read_sock(priv->binder_fd, wpas_binder_sock_handler,
-				     global, priv) < 0)
+	if (eloop_register_read_sock(
+		priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
 		goto err;
 
 	binder_manager = wpa_supplicant_binder::BinderManager::getInstance();
@@ -59,7 +58,7 @@
 	binder_manager->registerBinderService(global);
 	/* We may not need to store this binder manager reference in the
 	 * global data strucure because we've made it a singleton class. */
-	priv->binder_manager = (void *) binder_manager;
+	priv->binder_manager = (void *)binder_manager;
 
 	return priv;
 
@@ -68,7 +67,6 @@
 	return NULL;
 }
 
-
 void wpas_binder_deinit(struct wpas_binder_priv *priv)
 {
 	if (!priv)
@@ -79,28 +77,26 @@
 	android::IPCThreadState::shutdown();
 }
 
-
 int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
 {
 	if (!wpa_s->global->binder)
 		return 1;
 
 	wpa_supplicant_binder::BinderManager *binder_manager =
-		wpa_supplicant_binder::BinderManager::getInstance();
+	    wpa_supplicant_binder::BinderManager::getInstance();
 	if (!binder_manager)
 		return 1;
 
 	return binder_manager->registerInterface(wpa_s);
 }
 
-
 int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
 {
 	if (!wpa_s->global->binder)
 		return 1;
 
 	wpa_supplicant_binder::BinderManager *binder_manager =
-		wpa_supplicant_binder::BinderManager::getInstance();
+	    wpa_supplicant_binder::BinderManager::getInstance();
 	if (!binder_manager)
 		return 1;
 
diff --git a/wpa_supplicant/binder/binder.h b/wpa_supplicant/binder/binder.h
index a165074..019e327 100644
--- a/wpa_supplicant/binder/binder.h
+++ b/wpa_supplicant/binder/binder.h
@@ -7,8 +7,8 @@
  * See README for more details.
  */
 
-#ifndef BINDER_H
-#define BINDER_H
+#ifndef WPA_SUPPLICANT_BINDER_BINDER_H
+#define WPA_SUPPLICANT_BINDER_BINDER_H
 
 #ifdef _cplusplus
 extern "C" {
@@ -22,13 +22,13 @@
 struct wpas_binder_priv;
 struct wpa_global;
 
-struct wpas_binder_priv * wpas_binder_init(struct wpa_global *global);
+struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global);
 void wpas_binder_deinit(struct wpas_binder_priv *priv);
 
 #ifdef CONFIG_CTRL_IFACE_BINDER
 int wpas_binder_register_interface(struct wpa_supplicant *wpa_s);
 int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s);
-#else /* CONFIG_CTRL_IFACE_BINDER */
+#else  /* CONFIG_CTRL_IFACE_BINDER */
 static inline int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
 {
 	return 0;
@@ -43,4 +43,4 @@
 }
 #endif /* _cplusplus */
 
-#endif /* BINDER_H */
+#endif /* WPA_SUPPLICANT_BINDER_BINDER_H */
diff --git a/wpa_supplicant/binder/binder_constants.cpp b/wpa_supplicant/binder/binder_constants.cpp
new file mode 100644
index 0000000..0d452b1
--- /dev/null
+++ b/wpa_supplicant/binder/binder_constants.cpp
@@ -0,0 +1,18 @@
+/*
+ * binder interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "binder_constants.h"
+
+namespace wpa_supplicant_binder {
+namespace binder_constants {
+
+const char kServiceName[] = "wpa_supplicant";
+
+} /* namespace binder_constants */
+} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/binder_constants.h b/wpa_supplicant/binder/binder_constants.h
new file mode 100644
index 0000000..a4d9b55
--- /dev/null
+++ b/wpa_supplicant/binder/binder_constants.h
@@ -0,0 +1,21 @@
+/*
+ * binder interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H
+#define WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H
+
+namespace wpa_supplicant_binder {
+namespace binder_constants {
+
+extern const char kServiceName[];
+
+} /* namespace binder_constants */
+} /* namespace wpa_supplicant_binder */
+
+#endif /* WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H */
diff --git a/wpa_supplicant/binder/binder_i.h b/wpa_supplicant/binder/binder_i.h
index e8087b6..5140d6d 100644
--- a/wpa_supplicant/binder/binder_i.h
+++ b/wpa_supplicant/binder/binder_i.h
@@ -14,7 +14,8 @@
 extern "C" {
 #endif // _cplusplus
 
-struct wpas_binder_priv {
+struct wpas_binder_priv
+{
 	int binder_fd;
 	struct wpa_global *global;
 	void *binder_manager;
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
index 728f4b7..27e8ded 100644
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ b/wpa_supplicant/binder/binder_manager.cpp
@@ -9,27 +9,25 @@
 
 #include <binder/IServiceManager.h>
 
+#include "binder_constants.h"
 #include "binder_manager.h"
 
 extern "C" {
-#include "utils/includes.h"
 #include "utils/common.h"
+#include "utils/includes.h"
 }
 
 namespace wpa_supplicant_binder {
 
-const char BinderManager::kBinderServiceName[] = "fi.w1.wpa_supplicant";
 BinderManager *BinderManager::instance_ = NULL;
 
-
-BinderManager * BinderManager::getInstance()
+BinderManager *BinderManager::getInstance()
 {
 	if (!instance_)
 		instance_ = new BinderManager();
 	return instance_;
 }
 
-
 void BinderManager::destroyInstance()
 {
 	if (instance_)
@@ -37,20 +35,17 @@
 	instance_ = NULL;
 }
 
-
 int BinderManager::registerBinderService(struct wpa_global *global)
 {
 	/* Create the main binder service object and register with
 	 * system service manager. */
 	supplicant_object_ = new Supplicant(global);
-	android::String16 service_name(kBinderServiceName);
+	android::String16 service_name(binder_constants::kServiceName);
 	android::defaultServiceManager()->addService(
-		service_name,
-		android::IInterface::asBinder(supplicant_object_));
+	    service_name, android::IInterface::asBinder(supplicant_object_));
 	return 0;
 }
 
-
 int BinderManager::registerInterface(struct wpa_supplicant *wpa_s)
 {
 	if (!wpa_s)
@@ -73,7 +68,6 @@
 	return 0;
 }
 
-
 int BinderManager::unregisterInterface(struct wpa_supplicant *wpa_s)
 {
 	if (!wpa_s || !wpa_s->binder_object_key)
@@ -89,10 +83,9 @@
 	return 0;
 }
 
-
 int BinderManager::getIfaceBinderObjectByKey(
-	const void *iface_object_key,
-	android::sp<fi::w1::wpa_supplicant::IIface> *iface_object)
+    const void *iface_object_key,
+    android::sp<fi::w1::wpa_supplicant::IIface> *iface_object)
 {
 	if (!iface_object_key || !iface_object)
 		return 1;
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
index 687e740..d8b7dd0 100644
--- a/wpa_supplicant/binder/binder_manager.h
+++ b/wpa_supplicant/binder/binder_manager.h
@@ -7,14 +7,14 @@
  * See README for more details.
  */
 
-#ifndef BINDER_MANAGER_H
-#define BINDER_MANAGER_H
+#ifndef WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H
+#define WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H
 
 #include <map>
 #include <string>
 
-#include "supplicant.h"
 #include "iface.h"
+#include "supplicant.h"
 
 struct wpa_global;
 struct wpa_supplicant;
@@ -27,18 +27,17 @@
  * class which is created by the supplicant core and can be used
  * to get references to the binder objects.
  */
-class BinderManager {
+class BinderManager
+{
 public:
-	static const char kBinderServiceName[];
-
-	static BinderManager * getInstance();
+	static BinderManager *getInstance();
 	static void destroyInstance();
 	int registerBinderService(struct wpa_global *global);
 	int registerInterface(struct wpa_supplicant *wpa_s);
 	int unregisterInterface(struct wpa_supplicant *wpa_s);
 	int getIfaceBinderObjectByKey(
-		const void *iface_object_key,
-		android::sp<fi::w1::wpa_supplicant::IIface> *iface_object);
+	    const void *iface_object_key,
+	    android::sp<fi::w1::wpa_supplicant::IIface> *iface_object);
 
 private:
 	BinderManager() = default;
@@ -56,4 +55,4 @@
 
 } /* namespace wpa_supplicant_binder */
 
-#endif /* BINDER_MANAGER_H */
+#endif /* WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H */
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
index af2548d..c61b3b0 100644
--- a/wpa_supplicant/binder/iface.cpp
+++ b/wpa_supplicant/binder/iface.cpp
@@ -11,9 +11,6 @@
 
 namespace wpa_supplicant_binder {
 
-Iface::Iface(struct wpa_supplicant *wpa_s)
-	: wpa_s_(wpa_s)
-{
-}
+Iface::Iface(struct wpa_supplicant *wpa_s) : wpa_s_(wpa_s) {}
 
 } /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
index acc8e55..c0ee12c 100644
--- a/wpa_supplicant/binder/iface.h
+++ b/wpa_supplicant/binder/iface.h
@@ -7,14 +7,14 @@
  * See README for more details.
  */
 
-#ifndef IFACE_H
-#define IFACE_H
+#ifndef WPA_SUPPLICANT_BINDER_IFACE_H
+#define WPA_SUPPLICANT_BINDER_IFACE_H
 
 #include "fi/w1/wpa_supplicant/BnIface.h"
 
 extern "C" {
-#include "utils/includes.h"
 #include "utils/common.h"
+#include "utils/includes.h"
 #include "../wpa_supplicant_i.h"
 }
 
@@ -39,4 +39,4 @@
 
 } /* namespace wpa_supplicant_binder */
 
-#endif /* IFACE_H */
+#endif /* WPA_SUPPLICANT_BINDER_IFACE_H */
diff --git a/wpa_supplicant/binder/supplicant.cpp b/wpa_supplicant/binder/supplicant.cpp
index 6844e5a..76569b1 100644
--- a/wpa_supplicant/binder/supplicant.cpp
+++ b/wpa_supplicant/binder/supplicant.cpp
@@ -7,28 +7,24 @@
  * See README for more details.
  */
 
-#include "binder_manager.h"
 #include "supplicant.h"
+#include "binder_manager.h"
 
 namespace wpa_supplicant_binder {
 
-Supplicant::Supplicant(struct wpa_global *global)
-	: wpa_global_(global)
-{
-}
-
+Supplicant::Supplicant(struct wpa_global *global) : wpa_global_(global) {}
 
 android::binder::Status Supplicant::CreateInterface(
-	const android::os::PersistableBundle &params,
-	android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
+    const android::os::PersistableBundle &params,
+    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
 {
 	android::String16 driver, ifname, confname, bridge_ifname;
 
 	/* Check if required Ifname argument is missing */
 	if (!params.getString(android::String16("Ifname"), &ifname))
 		return android::binder::Status::fromServiceSpecificError(
-			ERROR_INVALID_ARGS,
-			android::String8("Ifname missing in params."));
+		    ERROR_INVALID_ARGS,
+		    android::String8("Ifname missing in params."));
 	/* Retrieve the remaining params from the dictionary */
 	params.getString(android::String16("Driver"), &driver);
 	params.getString(android::String16("ConfigFile"), &confname);
@@ -38,11 +34,12 @@
 	 * Try to get the wpa_supplicant record for this iface, return
 	 * an error if we already control it.
 	 */
-	if (wpa_supplicant_get_iface(wpa_global_,
-				     android::String8(ifname).string()) != NULL)
+	if (wpa_supplicant_get_iface(
+		wpa_global_, android::String8(ifname).string()) != NULL)
 		return android::binder::Status::fromServiceSpecificError(
-			ERROR_IFACE_EXISTS,
-			android::String8("wpa_supplicant already controls this interface."));
+		    ERROR_IFACE_EXISTS,
+		    android::String8("wpa_supplicant already controls this "
+				     "interface."));
 
 	android::binder::Status status;
 	struct wpa_supplicant *wpa_s = NULL;
@@ -52,36 +49,38 @@
 	iface.driver = os_strdup(android::String8(driver).string());
 	iface.ifname = os_strdup(android::String8(ifname).string());
 	iface.confname = os_strdup(android::String8(confname).string());
-	iface.bridge_ifname = os_strdup(
-		android::String8(bridge_ifname).string());
+	iface.bridge_ifname =
+	    os_strdup(android::String8(bridge_ifname).string());
 	/* Otherwise, have wpa_supplicant attach to it. */
 	wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
 	/* The supplicant core creates a corresponding binder object via
 	 * BinderManager when |wpa_supplicant_add_iface| is called. */
 	if (!wpa_s || !wpa_s->binder_object_key) {
 		status = android::binder::Status::fromServiceSpecificError(
-			ERROR_UNKNOWN,
-			android::String8("wpa_supplicant couldn't grab this interface."));
+		    ERROR_UNKNOWN,
+		    android::String8(
+			"wpa_supplicant couldn't grab this interface."));
 	} else {
 		BinderManager *binder_manager = BinderManager::getInstance();
 
 		if (!binder_manager ||
 		    binder_manager->getIfaceBinderObjectByKey(
-			    wpa_s->binder_object_key, aidl_return))
-			status = android::binder::Status::fromServiceSpecificError(
+			wpa_s->binder_object_key, aidl_return))
+			status =
+			    android::binder::Status::fromServiceSpecificError(
 				ERROR_UNKNOWN,
-				android::String8("wpa_supplicant encountered a binder error."));
+				android::String8("wpa_supplicant encountered a "
+						 "binder error."));
 		else
 			status = android::binder::Status::ok();
 	}
-	os_free((void *) iface.driver);
-	os_free((void *) iface.ifname);
-	os_free((void *) iface.confname);
-	os_free((void *) iface.bridge_ifname);
+	os_free((void *)iface.driver);
+	os_free((void *)iface.ifname);
+	os_free((void *)iface.confname);
+	os_free((void *)iface.bridge_ifname);
 	return status;
 }
 
-
 android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
 {
 	struct wpa_supplicant *wpa_s;
@@ -89,35 +88,38 @@
 	wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
 	if (!wpa_s || !wpa_s->binder_object_key)
 		return android::binder::Status::fromServiceSpecificError(
-			ERROR_IFACE_UNKNOWN,
-			android::String8("wpa_supplicant does not control this interface."));
+		    ERROR_IFACE_UNKNOWN,
+		    android::String8("wpa_supplicant does not control this "
+				     "interface."));
 	if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
 		return android::binder::Status::fromServiceSpecificError(
-			ERROR_UNKNOWN,
-			android::String8("wpa_supplicant couldn't remove this interface."));
+		    ERROR_UNKNOWN,
+		    android::String8(
+			"wpa_supplicant couldn't remove this interface."));
 	return android::binder::Status::ok();
 }
 
-
 android::binder::Status Supplicant::GetInterface(
-	const std::string &ifname,
-	android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
+    const std::string &ifname,
+    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
 {
 	struct wpa_supplicant *wpa_s;
 
 	wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
 	if (!wpa_s || !wpa_s->binder_object_key)
 		return android::binder::Status::fromServiceSpecificError(
-			ERROR_IFACE_UNKNOWN,
-			android::String8("wpa_supplicant does not control this interface."));
+		    ERROR_IFACE_UNKNOWN,
+		    android::String8(
+			"wpa_supplicant does not control this interface."));
 
 	BinderManager *binder_manager = BinderManager::getInstance();
 	if (!binder_manager ||
-	    binder_manager->getIfaceBinderObjectByKey(wpa_s->binder_object_key,
-						      aidl_return))
+	    binder_manager->getIfaceBinderObjectByKey(
+		wpa_s->binder_object_key, aidl_return))
 		return android::binder::Status::fromServiceSpecificError(
-			ERROR_UNKNOWN,
-			android::String8("wpa_supplicant encountered a binder error."));
+		    ERROR_UNKNOWN,
+		    android::String8(
+			"wpa_supplicant encountered a binder error."));
 
 	return android::binder::Status::ok();
 }
diff --git a/wpa_supplicant/binder/supplicant.h b/wpa_supplicant/binder/supplicant.h
index b96f4e6..136b99b 100644
--- a/wpa_supplicant/binder/supplicant.h
+++ b/wpa_supplicant/binder/supplicant.h
@@ -7,16 +7,16 @@
  * See README for more details.
  */
 
-#ifndef SUPPLICANT_H
-#define SUPPLICANT_H
+#ifndef WPA_SUPPLICANT_BINDER_SUPPLICANT_H
+#define WPA_SUPPLICANT_BINDER_SUPPLICANT_H
 
 #include "fi/w1/wpa_supplicant/BnSupplicant.h"
 #include "fi/w1/wpa_supplicant/IIface.h"
 #include "fi/w1/wpa_supplicant/ISupplicantCallbacks.h"
 
 extern "C" {
-#include "utils/includes.h"
 #include "utils/common.h"
+#include "utils/includes.h"
 #include "../wpa_supplicant_i.h"
 }
 
@@ -34,24 +34,22 @@
 	virtual ~Supplicant() = default;
 
 	android::binder::Status CreateInterface(
-		const android::os::PersistableBundle &params,
-		android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
-		override;
-	android::binder::Status RemoveInterface(
-		const std::string &ifname) override;
+	    const android::os::PersistableBundle &params,
+	    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) override;
+	android::binder::Status
+	RemoveInterface(const std::string &ifname) override;
 	android::binder::Status GetInterface(
-		const std::string &ifname,
-		android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
-		override;
+	    const std::string &ifname,
+	    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) override;
 
 private:
 	/* Raw pointer to the global structure maintained by the core. */
 	struct wpa_global *wpa_global_;
 	/* All the callback objects registered by the clients. */
 	std::vector<android::sp<fi::w1::wpa_supplicant::ISupplicantCallbacks>>
-		callbacks_;
+	    callbacks_;
 };
 
 } /* namespace wpa_supplicant_binder */
 
-#endif /* SUPPLICANT_H */
+#endif /* WPA_SUPPLICANT_BINDER_SUPPLICANT_H */
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index ce631dd..3f69936 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2005,6 +2005,7 @@
 	{ INT(dot11MeshHoldingTimeout) },
 #endif /* CONFIG_MESH */
 	{ INT(wpa_ptk_rekey) },
+	{ INT(group_rekey) },
 	{ STR(bgscan) },
 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
 #ifdef CONFIG_P2P
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index e72f844..994d5ea 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -785,6 +785,7 @@
 	INT_DEF(dot11MeshHoldingTimeout, DEFAULT_MESH_HOLDING_TIMEOUT);
 #endif /* CONFIG_MESH */
 	INT(wpa_ptk_rekey);
+	INT(group_rekey);
 	INT(ignore_broadcast_ssid);
 #ifdef CONFIG_HT_OVERRIDES
 	INT_DEF(disable_ht, DEFAULT_DISABLE_HT);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 1ecdfc0..010b594 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -487,6 +487,14 @@
 	int wpa_ptk_rekey;
 
 	/**
+	 * group_rekey - Group rekeying time in seconds
+	 *
+	 * This value, if non-zero, is used as the dot11RSNAConfigGroupRekeyTime
+	 * parameter when operating in Authenticator role in IBSS.
+	 */
+	int group_rekey;
+
+	/**
 	 * scan_freq - Array of frequencies to scan or %NULL for all
 	 *
 	 * This is an optional zero-terminated array of frequencies in
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index 199f04f..82ba3b0 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -933,6 +933,7 @@
 #ifdef CONFIG_HS20
 	INT(update_identifier);
 #endif /* CONFIG_HS20 */
+	INT(group_rekey);
 
 #undef STR
 #undef INT
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 4aa0f24..5017662 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -9127,16 +9127,7 @@
 		reply_len = wpa_supplicant_ctrl_iface_list_networks(
 			wpa_s, NULL, reply, reply_size);
 	} else if (os_strcmp(buf, "DISCONNECT") == 0) {
-#ifdef CONFIG_SME
-		wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
-		wpa_s->reassociate = 0;
-		wpa_s->disconnected = 1;
-		wpa_supplicant_cancel_sched_scan(wpa_s);
-		wpa_supplicant_cancel_scan(wpa_s);
-		wpa_supplicant_deauthenticate(wpa_s,
-					      WLAN_REASON_DEAUTH_LEAVING);
-		eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+		wpas_request_disconnection(wpa_s);
 	} else if (os_strcmp(buf, "SCAN") == 0) {
 		wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len);
 	} else if (os_strncmp(buf, "SCAN ", 5) == 0) {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index de6d216..8ccace5 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1475,10 +1475,7 @@
 					   struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->current_ssid != NULL) {
-		wpa_s->disconnected = 1;
-		wpa_supplicant_deauthenticate(wpa_s,
-					      WLAN_REASON_DEAUTH_LEAVING);
-
+		wpas_request_disconnection(wpa_s);
 		return NULL;
 	}
 
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
index e8f62ef..3561a24 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers.c
@@ -1069,8 +1069,7 @@
 DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
 					 struct wpa_supplicant *wpa_s)
 {
-	wpa_s->disconnected = 1;
-	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+	wpas_request_disconnection(wpa_s);
 
 	return wpas_dbus_new_success_reply(message);
 }
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 396a0dc..7a16b7a 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -969,4 +969,12 @@
 	return wpa_s->driver->p2p_lo_stop(wpa_s->drv_priv);
 }
 
+static inline int wpa_drv_set_default_scan_ies(struct wpa_supplicant *wpa_s,
+					       const u8 *ies, size_t len)
+{
+	if (!wpa_s->driver->set_default_scan_ies)
+		return -1;
+	return wpa_s->driver->set_default_scan_ies(wpa_s->drv_priv, ies, len);
+}
+
 #endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 50461b6..ef62d70 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2234,7 +2234,7 @@
 				       union wpa_event_data *data)
 {
 	u8 bssid[ETH_ALEN];
-	int ft_completed;
+	int ft_completed, already_authorized;
 	int new_bss = 0;
 
 #ifdef CONFIG_AP
@@ -2310,6 +2310,8 @@
 	if (wpa_s->l2)
 		l2_packet_notify_auth_start(wpa_s->l2);
 
+	already_authorized = data && data->assoc_info.authorized;
+
 	/*
 	 * Set portEnabled first to FALSE in order to get EAP state machine out
 	 * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
@@ -2318,11 +2320,12 @@
 	 * AUTHENTICATED without ever giving chance to EAP state machine to
 	 * reset the state.
 	 */
-	if (!ft_completed) {
+	if (!ft_completed && !already_authorized) {
 		eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
 		eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
 	}
-	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
+	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed ||
+	    already_authorized)
 		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
 	/* 802.1X::portControl = Auto */
 	eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
@@ -2414,7 +2417,7 @@
 	    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
 	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
 	    wpa_s->ibss_rsn == NULL) {
-		wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
+		wpa_s->ibss_rsn = ibss_rsn_init(wpa_s, wpa_s->current_ssid);
 		if (!wpa_s->ibss_rsn) {
 			wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
 			wpa_supplicant_deauthenticate(
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index c00db31..53d7d57 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -221,6 +221,7 @@
 	peer->supp = wpa_sm_init(ctx);
 	if (peer->supp == NULL) {
 		wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed");
+		os_free(ctx);
 		return -1;
 	}
 
@@ -404,7 +405,7 @@
 
 
 static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
-				    const u8 *own_addr)
+				    const u8 *own_addr, struct wpa_ssid *ssid)
 {
 	struct wpa_auth_config conf;
 	struct wpa_auth_callbacks cb;
@@ -418,7 +419,7 @@
 	conf.rsn_pairwise = WPA_CIPHER_CCMP;
 	conf.wpa_group = WPA_CIPHER_CCMP;
 	conf.eapol_version = 2;
-	conf.wpa_group_rekey = 600;
+	conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
 
 	os_memset(&cb, 0, sizeof(cb));
 	cb.ctx = ibss_rsn;
@@ -665,7 +666,8 @@
 }
 
 
-struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s)
+struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s,
+				struct wpa_ssid *ssid)
 {
 	struct ibss_rsn *ibss_rsn;
 
@@ -674,7 +676,7 @@
 		return NULL;
 	ibss_rsn->wpa_s = wpa_s;
 
-	if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr) < 0) {
+	if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr, ssid) < 0) {
 		ibss_rsn_deinit(ibss_rsn);
 		return NULL;
 	}
diff --git a/wpa_supplicant/ibss_rsn.h b/wpa_supplicant/ibss_rsn.h
index 67fae2d..626c543 100644
--- a/wpa_supplicant/ibss_rsn.h
+++ b/wpa_supplicant/ibss_rsn.h
@@ -51,7 +51,8 @@
 };
 
 
-struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s);
+struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s,
+				struct wpa_ssid *ssid);
 void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn);
 int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr);
 void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac);
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index 5b5c3e6..91667b0 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -18,6 +18,7 @@
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "bss.h"
+#include "scan.h"
 
 /* type + length + oui + oui type */
 #define MBO_IE_HEADER 6
@@ -810,4 +811,5 @@
 	cell_capa[6] = mbo_cell_capa;
 
 	wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7);
+	wpa_supplicant_set_default_scan_ies(wpa_s);
 }
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index cb8df66..31eeb38 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1076,7 +1076,7 @@
 		   "go_dev_addr=" MACSTR,
 		   MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
 
-	return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+	return !!(group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP);
 }
 
 
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 119da28..371c16a 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -426,6 +426,39 @@
 #endif /* CONFIG_INTERWORKING */
 
 
+void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
+{
+	struct wpabuf *default_ies = NULL;
+	u8 ext_capab[18];
+	int ext_capab_len;
+	enum wpa_driver_if_type type = WPA_IF_STATION;
+
+#ifdef CONFIG_P2P
+	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
+		type = WPA_IF_P2P_CLIENT;
+#endif /* CONFIG_P2P */
+
+	wpa_drv_get_ext_capa(wpa_s, type);
+
+	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
+					     sizeof(ext_capab));
+	if (ext_capab_len > 0 &&
+	    wpabuf_resize(&default_ies, ext_capab_len) == 0)
+		wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
+
+#ifdef CONFIG_MBO
+	/* Send cellular capabilities for potential MBO STAs */
+	if (wpabuf_resize(&default_ies, 9) == 0)
+		wpas_mbo_scan_ie(wpa_s, default_ies);
+#endif /* CONFIG_MBO */
+
+	if (default_ies)
+		wpa_drv_set_default_scan_ies(wpa_s, wpabuf_head(default_ies),
+					     wpabuf_len(default_ies));
+	wpabuf_free(default_ies);
+}
+
+
 static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 {
 	struct wpabuf *extra_ie = NULL;
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 9f8d04e..b2bb386 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -56,5 +56,6 @@
 void scan_snr(struct wpa_scan_res *res);
 void scan_est_throughput(struct wpa_supplicant *wpa_s,
 			 struct wpa_scan_res *res);
+void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s);
 
 #endif /* SCAN_H */
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 7012dfb..ca3d8f8 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -14,6 +14,7 @@
 #include <dirent.h>
 #endif /* CONFIG_CTRL_IFACE_UNIX */
 
+#include "common/cli.h"
 #include "common/wpa_ctrl.h"
 #include "utils/common.h"
 #include "utils/eloop.h"
@@ -30,42 +31,6 @@
 "wpa_cli v" VERSION_STR "\n"
 "Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors";
 
-
-static const char *const wpa_cli_license =
-"This software may be distributed under the terms of the BSD license.\n"
-"See README for more details.\n";
-
-static const char *const wpa_cli_full_license =
-"This software may be distributed under the terms of the BSD license.\n"
-"\n"
-"Redistribution and use in source and binary forms, with or without\n"
-"modification, are permitted provided that the following conditions are\n"
-"met:\n"
-"\n"
-"1. Redistributions of source code must retain the above copyright\n"
-"   notice, this list of conditions and the following disclaimer.\n"
-"\n"
-"2. Redistributions in binary form must reproduce the above copyright\n"
-"   notice, this list of conditions and the following disclaimer in the\n"
-"   documentation and/or other materials provided with the distribution.\n"
-"\n"
-"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
-"   names of its contributors may be used to endorse or promote products\n"
-"   derived from this software without specific prior written permission.\n"
-"\n"
-"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
-"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
-"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
-"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
-"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
-"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
-"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
-"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
-"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
-"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
-"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
-"\n";
-
 #define VENDOR_ELEM_FRAME_ID \
 	"  0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
 	"3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
@@ -90,11 +55,6 @@
 static int interactive = 0;
 static char *ifname_prefix = NULL;
 
-struct cli_txt_entry {
-	struct dl_list list;
-	char *txt;
-};
-
 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
@@ -130,168 +90,6 @@
 }
 
 
-static void cli_txt_list_free(struct cli_txt_entry *e)
-{
-	dl_list_del(&e->list);
-	os_free(e->txt);
-	os_free(e);
-}
-
-
-static void cli_txt_list_flush(struct dl_list *list)
-{
-	struct cli_txt_entry *e;
-	while ((e = dl_list_first(list, struct cli_txt_entry, list)))
-		cli_txt_list_free(e);
-}
-
-
-static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
-					       const char *txt)
-{
-	struct cli_txt_entry *e;
-	dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
-		if (os_strcmp(e->txt, txt) == 0)
-			return e;
-	}
-	return NULL;
-}
-
-
-static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
-{
-	struct cli_txt_entry *e;
-	e = cli_txt_list_get(txt_list, txt);
-	if (e)
-		cli_txt_list_free(e);
-}
-
-
-static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
-{
-	u8 addr[ETH_ALEN];
-	char buf[18];
-	if (hwaddr_aton(txt, addr) < 0)
-		return;
-	os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
-	cli_txt_list_del(txt_list, buf);
-}
-
-
-#ifdef CONFIG_P2P
-static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt,
-				  int separator)
-{
-	const char *end;
-	char *buf;
-	end = os_strchr(txt, separator);
-	if (end == NULL)
-		end = txt + os_strlen(txt);
-	buf = dup_binstr(txt, end - txt);
-	if (buf == NULL)
-		return;
-	cli_txt_list_del(txt_list, buf);
-	os_free(buf);
-}
-#endif /* CONFIG_P2P */
-
-
-static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
-{
-	struct cli_txt_entry *e;
-	e = cli_txt_list_get(txt_list, txt);
-	if (e)
-		return 0;
-	e = os_zalloc(sizeof(*e));
-	if (e == NULL)
-		return -1;
-	e->txt = os_strdup(txt);
-	if (e->txt == NULL) {
-		os_free(e);
-		return -1;
-	}
-	dl_list_add(txt_list, &e->list);
-	return 0;
-}
-
-
-#ifdef CONFIG_P2P
-static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
-{
-	u8 addr[ETH_ALEN];
-	char buf[18];
-	if (hwaddr_aton(txt, addr) < 0)
-		return -1;
-	os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
-	return cli_txt_list_add(txt_list, buf);
-}
-#endif /* CONFIG_P2P */
-
-
-static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt,
-				 int separator)
-{
-	const char *end;
-	char *buf;
-	int ret;
-	end = os_strchr(txt, separator);
-	if (end == NULL)
-		end = txt + os_strlen(txt);
-	buf = dup_binstr(txt, end - txt);
-	if (buf == NULL)
-		return -1;
-	ret = cli_txt_list_add(txt_list, buf);
-	os_free(buf);
-	return ret;
-}
-
-
-static char ** cli_txt_list_array(struct dl_list *txt_list)
-{
-	unsigned int i, count = dl_list_len(txt_list);
-	char **res;
-	struct cli_txt_entry *e;
-
-	res = os_calloc(count + 1, sizeof(char *));
-	if (res == NULL)
-		return NULL;
-
-	i = 0;
-	dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
-		res[i] = os_strdup(e->txt);
-		if (res[i] == NULL)
-			break;
-		i++;
-	}
-
-	return res;
-}
-
-
-static int get_cmd_arg_num(const char *str, int pos)
-{
-	int arg = 0, i;
-
-	for (i = 0; i <= pos; i++) {
-		if (str[i] != ' ') {
-			arg++;
-			while (i <= pos && str[i] != ' ')
-				i++;
-		}
-	}
-
-	if (arg > 0)
-		arg--;
-	return arg;
-}
-
-
-static int str_starts(const char *src, const char *match)
-{
-	return os_strncmp(src, match, os_strlen(match)) == 0;
-}
-
-
 static int wpa_cli_show_event(const char *event)
 {
 	const char *start;
@@ -458,36 +256,6 @@
 }
 
 
-static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
-		     char *argv[])
-{
-	int i, res;
-	char *pos, *end;
-
-	pos = buf;
-	end = buf + buflen;
-
-	res = os_snprintf(pos, end - pos, "%s", cmd);
-	if (os_snprintf_error(end - pos, res))
-		goto fail;
-	pos += res;
-
-	for (i = 0; i < argc; i++) {
-		res = os_snprintf(pos, end - pos, " %s", argv[i]);
-		if (os_snprintf_error(end - pos, res))
-			goto fail;
-		pos += res;
-	}
-
-	buf[buflen - 1] = '\0';
-	return 0;
-
-fail:
-	printf("Too long command\n");
-	return -1;
-}
-
-
 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
 		       int argc, char *argv[])
 {
@@ -587,7 +355,7 @@
 
 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
-	printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
+	printf("%s\n\n%s\n", wpa_cli_version, cli_full_license);
 	return 0;
 }
 
@@ -1824,6 +1592,48 @@
 }
 
 
+static char ** wpa_cli_complete_get_capability(const char *str, int pos)
+{
+	int arg = get_cmd_arg_num(str, pos);
+	const char *fields[] = {
+		"eap", "pairwise", "group", "group_mgmt", "key_mgmt",
+		"proto", "auth_alg", "modes", "channels", "freq",
+#ifdef CONFIG_TDLS
+		"tdls",
+#endif /* CONFIG_TDLS */
+#ifdef CONFIG_ERP
+		"erp",
+#endif /* CONFIG_ERP */
+#ifdef CONFIG_FIPS
+		"fips",
+#endif /* CONFIG_FIPS */
+#ifdef CONFIG_ACS
+		"acs",
+#endif /* CONFIG_ACS */
+	};
+	int i, num_fields = ARRAY_SIZE(fields);
+	char **res = NULL;
+
+	if (arg == 1) {
+		res = os_calloc(num_fields + 1, sizeof(char *));
+		if (res == NULL)
+			return NULL;
+		for (i = 0; i < num_fields; i++) {
+			res[i] = os_strdup(fields[i]);
+			if (res[i] == NULL)
+				return res;
+		}
+	}
+	if (arg == 2) {
+		res = os_calloc(1 + 1, sizeof(char *));
+		if (res == NULL)
+			return NULL;
+		res[0] = os_strdup("strict");
+	}
+	return res;
+}
+
+
 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
 {
 	printf("Available interfaces:\n");
@@ -3100,8 +2910,8 @@
 	{ "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
 	  cli_cmd_flag_none,
 	  "<<idx> | <bssid>> = get detailed scan result info" },
-	{ "get_capability", wpa_cli_cmd_get_capability, NULL,
-	  cli_cmd_flag_none,
+	{ "get_capability", wpa_cli_cmd_get_capability,
+	  wpa_cli_complete_get_capability, cli_cmd_flag_none,
 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
 	  "= get capabilities" },
 	{ "reconfigure", wpa_cli_cmd_reconfigure, NULL,
@@ -3705,12 +3515,6 @@
 }
 
 
-static int str_match(const char *a, const char *b)
-{
-	return os_strncmp(a, b, os_strlen(b)) == 0;
-}
-
-
 static int wpa_cli_exec(const char *program, const char *arg1,
 			const char *arg2)
 {
@@ -3766,7 +3570,7 @@
 			pos = prev;
 	}
 
-	if (str_match(pos, WPA_EVENT_CONNECTED)) {
+	if (str_starts(pos, WPA_EVENT_CONNECTED)) {
 		int new_id = -1;
 		os_unsetenv("WPA_ID");
 		os_unsetenv("WPA_ID_STR");
@@ -3802,48 +3606,48 @@
 			wpa_cli_last_id = new_id;
 			wpa_cli_exec(action_file, ifname, "CONNECTED");
 		}
-	} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
+	} else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) {
 		if (wpa_cli_connected) {
 			wpa_cli_connected = 0;
 			wpa_cli_exec(action_file, ifname, "DISCONNECTED");
 		}
-	} else if (str_match(pos, AP_EVENT_ENABLED)) {
+	} else if (str_starts(pos, AP_EVENT_ENABLED)) {
 		wpa_cli_exec(action_file, ctrl_ifname, pos);
-	} else if (str_match(pos, AP_EVENT_DISABLED)) {
+	} else if (str_starts(pos, AP_EVENT_DISABLED)) {
 		wpa_cli_exec(action_file, ctrl_ifname, pos);
-	} else if (str_match(pos, MESH_GROUP_STARTED)) {
+	} else if (str_starts(pos, MESH_GROUP_STARTED)) {
 		wpa_cli_exec(action_file, ctrl_ifname, pos);
-	} else if (str_match(pos, MESH_GROUP_REMOVED)) {
+	} else if (str_starts(pos, MESH_GROUP_REMOVED)) {
 		wpa_cli_exec(action_file, ctrl_ifname, pos);
-	} else if (str_match(pos, MESH_PEER_CONNECTED)) {
+	} else if (str_starts(pos, MESH_PEER_CONNECTED)) {
 		wpa_cli_exec(action_file, ctrl_ifname, pos);
-	} else if (str_match(pos, MESH_PEER_DISCONNECTED)) {
+	} else if (str_starts(pos, MESH_PEER_DISCONNECTED)) {
 		wpa_cli_exec(action_file, ctrl_ifname, pos);
-	} else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
+	} else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
+	} else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
+	} else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
+	} else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
+	} else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, WPS_EVENT_SUCCESS)) {
+	} else if (str_starts(pos, WPS_EVENT_SUCCESS)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, WPS_EVENT_FAIL)) {
+	} else if (str_starts(pos, WPS_EVENT_FAIL)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, AP_STA_CONNECTED)) {
+	} else if (str_starts(pos, AP_STA_CONNECTED)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, AP_STA_DISCONNECTED)) {
+	} else if (str_starts(pos, AP_STA_DISCONNECTED)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
+	} else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
+	} else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
+	} else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
 		wpa_cli_exec(action_file, ifname, pos);
-	} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
+	} else if (str_starts(pos, WPA_EVENT_TERMINATING)) {
 		printf("wpa_supplicant is terminating - stop monitoring\n");
 		wpa_cli_quit = 1;
 	}
@@ -3953,7 +3757,7 @@
 			pos = msg;
 	}
 
-	if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
+	if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
 		edit_clear_line();
 		printf("\rConnection to wpa_supplicant lost - trying to "
 		       "reconnect\n");
@@ -4004,37 +3808,6 @@
 	}
 }
 
-#define max_args 10
-
-static int tokenize_cmd(char *cmd, char *argv[])
-{
-	char *pos;
-	int argc = 0;
-
-	pos = cmd;
-	for (;;) {
-		while (*pos == ' ')
-			pos++;
-		if (*pos == '\0')
-			break;
-		argv[argc] = pos;
-		argc++;
-		if (argc == max_args)
-			break;
-		if (*pos == '"') {
-			char *pos2 = os_strrchr(pos, '"');
-			if (pos2)
-				pos = pos2 + 1;
-		}
-		while (*pos != '\0' && *pos != ' ')
-			pos++;
-		if (*pos == ' ')
-			*pos++ = '\0';
-	}
-
-	return argc;
-}
-
 
 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
 {
@@ -4444,7 +4217,7 @@
 	interactive = (argc == optind) && (action_file == NULL);
 
 	if (interactive)
-		printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
+		printf("%s\n\n%s\n\n", wpa_cli_version, cli_license);
 
 	if (eloop_init())
 		return -1;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7ed7efa..0add89d 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -4875,6 +4875,8 @@
 	wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
 #endif /* CONFIG_MBO */
 
+	wpa_supplicant_set_default_scan_ies(wpa_s);
+
 	return 0;
 }
 
@@ -6022,6 +6024,27 @@
 }
 
 
+/**
+ * wpas_request_disconnection - Request disconnection
+ * @wpa_s: Pointer to the network interface
+ *
+ * This function is used to request disconnection from the currently connected
+ * network. This will stop any ongoing scans and initiate deauthentication.
+ */
+void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_SME
+	wpa_s->sme.prev_bssid_set = 0;
+#endif /* CONFIG_SME */
+	wpa_s->reassociate = 0;
+	wpa_s->disconnected = 1;
+	wpa_supplicant_cancel_sched_scan(wpa_s);
+	wpa_supplicant_cancel_scan(wpa_s);
+	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+	eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+}
+
+
 void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
 		    struct wpa_used_freq_data *freqs_data,
 		    unsigned int len)
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 1d86a71..6ece942 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -896,6 +896,10 @@
 # wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to
 # enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies.
 #
+# group_rekey: Group rekeying time in seconds. This value, if non-zero, is used
+# as the dot11RSNAConfigGroupRekeyTime parameter when operating in
+# Authenticator role in IBSS.
+#
 # Following fields are only used with internal EAP implementation.
 # eap: space-separated list of accepted EAP methods
 #	MD5 = EAP-MD5 (unsecure and does not generate keying material ->
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index dd6a60d..0f1541e 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1162,6 +1162,7 @@
 int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
 		    size_t ssid_len);
 void wpas_request_connection(struct wpa_supplicant *wpa_s);
+void wpas_request_disconnection(struct wpa_supplicant *wpa_s);
 int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
 int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style);
 int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);