aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/.config2
-rw-r--r--wpa_supplicant/.gitignore1
-rw-r--r--wpa_supplicant/Android.mk67
-rw-r--r--wpa_supplicant/Makefile91
-rw-r--r--wpa_supplicant/README59
-rw-r--r--wpa_supplicant/README-P2P15
-rw-r--r--wpa_supplicant/README-WPS5
-rw-r--r--wpa_supplicant/ap.c172
-rw-r--r--wpa_supplicant/ap.h5
-rw-r--r--wpa_supplicant/bgscan_learn.c12
-rw-r--r--wpa_supplicant/bss.c65
-rw-r--r--wpa_supplicant/bss.h10
-rw-r--r--wpa_supplicant/config.c141
-rw-r--r--wpa_supplicant/config.h64
-rw-r--r--wpa_supplicant/config_file.c46
-rw-r--r--wpa_supplicant/config_ssid.h14
-rw-r--r--wpa_supplicant/config_winreg.c4
-rw-r--r--wpa_supplicant/ctrl_iface.c759
-rw-r--r--wpa_supplicant/ctrl_iface.h15
-rw-r--r--wpa_supplicant/ctrl_iface_unix.c2
-rw-r--r--wpa_supplicant/dbus/dbus_dict_helpers.c24
-rw-r--r--wpa_supplicant/dbus/dbus_dict_helpers.h3
-rw-r--r--wpa_supplicant/dbus/dbus_new.c490
-rw-r--r--wpa_supplicant/dbus/dbus_new.h18
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.c1485
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.h227
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.c888
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.h74
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_wps.c107
-rw-r--r--wpa_supplicant/dbus/dbus_new_helpers.c440
-rw-r--r--wpa_supplicant/dbus/dbus_new_helpers.h25
-rw-r--r--wpa_supplicant/dbus/dbus_new_introspect.c7
-rw-r--r--wpa_supplicant/dbus/dbus_old.c1
-rw-r--r--wpa_supplicant/dbus/dbus_old_handlers.c10
-rw-r--r--wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service4
-rw-r--r--wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service4
-rw-r--r--wpa_supplicant/defconfig39
-rw-r--r--wpa_supplicant/driver_i.h126
-rw-r--r--wpa_supplicant/eap_register.c1
-rw-r--r--wpa_supplicant/eapol_test.c52
-rw-r--r--wpa_supplicant/events.c513
-rw-r--r--wpa_supplicant/examples/udhcpd-p2p.conf4
-rwxr-xr-xwpa_supplicant/examples/wps-ap-cli78
-rw-r--r--wpa_supplicant/gas_query.c481
-rw-r--r--wpa_supplicant/gas_query.h61
-rw-r--r--wpa_supplicant/ibss_rsn.c6
-rw-r--r--wpa_supplicant/interworking.c1138
-rw-r--r--wpa_supplicant/interworking.h31
-rw-r--r--wpa_supplicant/mlme.c3181
-rw-r--r--wpa_supplicant/mlme.h121
-rw-r--r--wpa_supplicant/notify.c30
-rw-r--r--wpa_supplicant/notify.h9
-rw-r--r--wpa_supplicant/offchannel.c314
-rw-r--r--wpa_supplicant/offchannel.h39
-rw-r--r--wpa_supplicant/p2p_supplicant.c891
-rw-r--r--wpa_supplicant/p2p_supplicant.h33
-rw-r--r--wpa_supplicant/scan.c620
-rw-r--r--wpa_supplicant/scan.h5
-rw-r--r--wpa_supplicant/sme.c63
-rw-r--r--wpa_supplicant/wpa_cli.c457
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.cpp4
-rw-r--r--wpa_supplicant/wpa_gui-qt4/signalbar.cpp64
-rw-r--r--wpa_supplicant/wpa_gui-qt4/signalbar.h34
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpa_gui.pro2
-rw-r--r--wpa_supplicant/wpa_gui/.gitignore3
-rw-r--r--wpa_supplicant/wpa_gui/eventhistory.ui125
-rw-r--r--wpa_supplicant/wpa_gui/eventhistory.ui.h41
-rw-r--r--wpa_supplicant/wpa_gui/main.cpp30
-rw-r--r--wpa_supplicant/wpa_gui/networkconfig.ui475
-rw-r--r--wpa_supplicant/wpa_gui/networkconfig.ui.h552
-rw-r--r--wpa_supplicant/wpa_gui/scanresults.ui179
-rw-r--r--wpa_supplicant/wpa_gui/scanresults.ui.h101
-rwxr-xr-xwpa_supplicant/wpa_gui/setup-mingw-cross-compiling11
-rw-r--r--wpa_supplicant/wpa_gui/userdatarequest.ui163
-rw-r--r--wpa_supplicant/wpa_gui/userdatarequest.ui.h72
-rw-r--r--wpa_supplicant/wpa_gui/wpa_gui.pro50
-rw-r--r--wpa_supplicant/wpa_gui/wpagui.ui471
-rw-r--r--wpa_supplicant/wpa_gui/wpagui.ui.h730
-rw-r--r--wpa_supplicant/wpa_gui/wpamsg.h34
-rw-r--r--wpa_supplicant/wpa_priv.c4
-rw-r--r--wpa_supplicant/wpa_supplicant.c329
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h179
-rw-r--r--wpa_supplicant/wpas_glue.c150
-rw-r--r--wpa_supplicant/wpas_glue.h8
-rw-r--r--wpa_supplicant/wps_supplicant.c33
85 files changed, 7886 insertions, 9607 deletions
diff --git a/wpa_supplicant/.config b/wpa_supplicant/.config
index 14e509f..29f4dbe 100644
--- a/wpa_supplicant/.config
+++ b/wpa_supplicant/.config
@@ -398,5 +398,7 @@ CONFIG_ANDROID_LOG=y
#CONFIG_DELAYED_MIC_ERROR_REPORT=y
# Enable P2P
+# IEEE 802.11n (High Throughput) support (mainly for AP mode)
+CONFIG_IEEE80211N=y
CONFIG_P2P=y
CONFIG_AP=y
diff --git a/wpa_supplicant/.gitignore b/wpa_supplicant/.gitignore
new file mode 100644
index 0000000..0e3ad1b
--- /dev/null
+++ b/wpa_supplicant/.gitignore
@@ -0,0 +1 @@
+*.service
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index f1ef67f..ac92248 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -31,19 +31,10 @@ include $(LOCAL_PATH)/.config
# To ignore possible wrong network configurations
L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
-L_CFLAGS += -DVERSION_STR_POSTFIX=\"-$(PLATFORM_VERSION)\"
-
+L_CFLAGS += -DANDROID_P2P
# Set Android log name
L_CFLAGS += -DANDROID_LOG_NAME=\"wpa_supplicant\"
-ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
-L_CFLAGS += -DANDROID_BRCM_P2P_PATCH
-endif
-
-ifdef CONFIG_ROAMING
-L_CFLAGS += -DCONFIG_ROAMING
-endif
-
# Use Android specific directory for control interface sockets
L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/misc/wifi/sockets\"
L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/system/wpa_supplicant\"
@@ -94,6 +85,7 @@ OBJS_p += src/utils/wpa_debug.c
OBJS_p += src/utils/wpabuf.c
OBJS_c = wpa_cli.c src/common/wpa_ctrl.c
OBJS_c += src/utils/wpa_debug.c
+OBJS_c += src/utils/common.c
OBJS_d =
OBJS_priv =
@@ -187,11 +179,15 @@ endif
ifdef CONFIG_TDLS
L_CFLAGS += -DCONFIG_TDLS
-OBJS += src/rsn_supp/tdls.o
+OBJS += src/rsn_supp/tdls.c
NEED_SHA256=y
NEED_AES_OMAC1=y
endif
+ifdef CONFIG_TDLS_TESTING
+L_CFLAGS += -DCONFIG_TDLS_TESTING
+endif
+
ifdef CONFIG_PEERKEY
L_CFLAGS += -DCONFIG_PEERKEY
endif
@@ -231,12 +227,22 @@ OBJS += src/p2p/p2p_dev_disc.c
OBJS += src/p2p/p2p_group.c
OBJS += src/ap/p2p_hostapd.c
L_CFLAGS += -DCONFIG_P2P
+NEED_GAS=y
+NEED_OFFCHANNEL=y
NEED_80211_COMMON=y
+CONFIG_WPS=y
+CONFIG_AP=y
ifdef CONFIG_P2P_STRICT
L_CFLAGS += -DCONFIG_P2P_STRICT
endif
endif
+ifdef CONFIG_INTERWORKING
+OBJS += interworking.c
+L_CFLAGS += -DCONFIG_INTERWORKING
+NEED_GAS=y
+endif
+
ifdef CONFIG_NO_WPA2
L_CFLAGS += -DCONFIG_NO_WPA2
endif
@@ -701,8 +707,10 @@ OBJS += src/ap/ap_mlme.c
OBJS += src/ap/ieee802_1x.c
OBJS += src/eapol_auth/eapol_auth_sm.c
OBJS += src/ap/ieee802_11_auth.c
+OBJS += src/ap/ieee802_11_shared.c
OBJS += src/ap/drv_callbacks.c
OBJS += src/ap/ap_drv_ops.c
+OBJS += src/ap/beacon.c
ifdef CONFIG_IEEE80211N
OBJS += src/ap/ieee802_11_ht.c
endif
@@ -720,7 +728,6 @@ L_CFLAGS += -DCONFIG_IEEE80211N
endif
ifdef NEED_AP_MLME
-OBJS += src/ap/beacon.c
OBJS += src/ap/wmm.c
OBJS += src/ap/ap_list.c
OBJS += src/ap/ieee802_11.c
@@ -804,6 +811,7 @@ endif
ifdef NEED_MILENAGE
OBJS += src/crypto/milenage.c
+NEED_AES_ENCBLOCK=y
endif
ifdef CONFIG_PKCS12
@@ -836,6 +844,10 @@ ifndef CONFIG_TLS
CONFIG_TLS=openssl
endif
+ifdef CONFIG_TLSV11
+L_CFLAGS += -DCONFIG_TLSV11
+endif
+
ifeq ($(CONFIG_TLS), openssl)
ifdef TLS_FUNCS
L_CFLAGS += -DEAP_TLS_OPENSSL
@@ -855,10 +867,6 @@ ifeq ($(CONFIG_TLS), gnutls)
ifdef TLS_FUNCS
OBJS += src/crypto/tls_gnutls.c
LIBS += -lgnutls -lgpg-error
-ifdef CONFIG_GNUTLS_EXTRA
-L_CFLAGS += -DCONFIG_GNUTLS_EXTRA
-LIBS += -lgnutls-extra
-endif
endif
OBJS += src/crypto/crypto_gnutls.c
OBJS_p += src/crypto/crypto_gnutls.c
@@ -1259,12 +1267,6 @@ OBJS += sme.c
L_CFLAGS += -DCONFIG_SME
endif
-ifdef CONFIG_CLIENT_MLME
-OBJS += mlme.c
-L_CFLAGS += -DCONFIG_CLIENT_MLME
-NEED_80211_COMMON=y
-endif
-
ifdef NEED_80211_COMMON
OBJS += src/common/ieee802_11_common.c
endif
@@ -1317,7 +1319,21 @@ L_CFLAGS += -DCONFIG_BGSCAN
OBJS += bgscan.c
endif
-OBJS_wpa_rm := ctrl_iface.c mlme.c ctrl_iface_unix.c
+ifdef NEED_GAS
+OBJS += ../src/common/gas.c
+OBJS += gas_query.c
+L_CFLAGS += -DCONFIG_GAS
+NEED_OFFCHANNEL=y
+endif
+
+ifdef NEED_OFFCHANNEL
+OBJS += offchannel.c
+L_CFLAGS += -DCONFIG_OFFCHANNEL
+endif
+
+OBJS += src/drivers/driver_common.c
+
+OBJS_wpa_rm := ctrl_iface.c ctrl_iface_unix.c
OBJS_wpa := $(filter-out $(OBJS_wpa_rm),$(OBJS)) $(OBJS_h) tests/test_wpa.c
ifdef CONFIG_AUTHENTICATOR
OBJS_wpa += tests/link_test.c
@@ -1405,7 +1421,10 @@ endif
ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
LOCAL_STATIC_LIBRARIES += $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB)
endif
-LOCAL_SHARED_LIBRARIES := libc libcutils libcrypto libssl
+LOCAL_SHARED_LIBRARIES := libc libcutils
+ifeq ($(CONFIG_TLS), openssl)
+LOCAL_SHARED_LIBRARIES += libcrypto libssl
+endif
ifdef CONFIG_DRIVER_NL80211
LOCAL_STATIC_LIBRARIES += libnl_2
endif
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 3536084..0832f10 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -21,6 +21,14 @@ ifndef CONFIG_NO_WPA_PASSPHRASE
ALL += wpa_passphrase
endif
+ALL += systemd/wpa_supplicant.service
+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
+
+
all: verify_config $(ALL) dynamic_eap_methods
verify_config:
@@ -58,6 +66,7 @@ OBJS_p += ../src/utils/wpa_debug.o
OBJS_p += ../src/utils/wpabuf.o
OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o
OBJS_c += ../src/utils/wpa_debug.o
+OBJS_c += ../src/utils/common.o
ifndef CONFIG_OS
ifdef CONFIG_NATIVE_WINDOWS
@@ -80,6 +89,7 @@ CFLAGS += -DWPA_TRACE
OBJS += ../src/utils/trace.o
OBJS_p += ../src/utils/trace.o
OBJS_c += ../src/utils/trace.o
+OBJS_priv += ../src/utils/trace.o
LDFLAGS += -rdynamic
CFLAGS += -funwind-tables
ifdef CONFIG_WPA_TRACE_BFD
@@ -154,6 +164,10 @@ NEED_SHA256=y
NEED_AES_OMAC1=y
endif
+ifdef CONFIG_TDLS_TESTING
+CFLAGS += -DCONFIG_TDLS_TESTING
+endif
+
ifdef CONFIG_PEERKEY
CFLAGS += -DCONFIG_PEERKEY
endif
@@ -193,12 +207,22 @@ OBJS += ../src/p2p/p2p_dev_disc.o
OBJS += ../src/p2p/p2p_group.o
OBJS += ../src/ap/p2p_hostapd.o
CFLAGS += -DCONFIG_P2P
+NEED_GAS=y
+NEED_OFFCHANNEL=y
NEED_80211_COMMON=y
+CONFIG_WPS=y
+CONFIG_AP=y
ifdef CONFIG_P2P_STRICT
CFLAGS += -DCONFIG_P2P_STRICT
endif
endif
+ifdef CONFIG_INTERWORKING
+OBJS += interworking.o
+CFLAGS += -DCONFIG_INTERWORKING
+NEED_GAS=y
+endif
+
ifdef CONFIG_NO_WPA2
CFLAGS += -DCONFIG_NO_WPA2
endif
@@ -662,8 +686,10 @@ OBJS += ../src/ap/ap_mlme.o
OBJS += ../src/ap/ieee802_1x.o
OBJS += ../src/eapol_auth/eapol_auth_sm.o
OBJS += ../src/ap/ieee802_11_auth.o
+OBJS += ../src/ap/ieee802_11_shared.o
OBJS += ../src/ap/drv_callbacks.o
OBJS += ../src/ap/ap_drv_ops.o
+OBJS += ../src/ap/beacon.o
ifdef CONFIG_IEEE80211N
OBJS += ../src/ap/ieee802_11_ht.o
endif
@@ -681,7 +707,6 @@ CFLAGS += -DCONFIG_IEEE80211N
endif
ifdef NEED_AP_MLME
-OBJS += ../src/ap/beacon.o
OBJS += ../src/ap/wmm.o
OBJS += ../src/ap/ap_list.o
OBJS += ../src/ap/ieee802_11.o
@@ -765,6 +790,7 @@ endif
ifdef NEED_MILENAGE
OBJS += ../src/crypto/milenage.o
+NEED_AES_ENCBLOCK=y
endif
ifdef CONFIG_PKCS12
@@ -797,6 +823,15 @@ ifndef CONFIG_TLS
CONFIG_TLS=openssl
endif
+ifdef CONFIG_TLSV11
+CFLAGS += -DCONFIG_TLSV11
+endif
+
+ifdef CONFIG_TLSV12
+CFLAGS += -DCONFIG_TLSV12
+NEED_SHA256=y
+endif
+
ifeq ($(CONFIG_TLS), openssl)
ifdef TLS_FUNCS
CFLAGS += -DEAP_TLS_OPENSSL
@@ -816,10 +851,6 @@ ifeq ($(CONFIG_TLS), gnutls)
ifdef TLS_FUNCS
OBJS += ../src/crypto/tls_gnutls.o
LIBS += -lgnutls -lgpg-error
-ifdef CONFIG_GNUTLS_EXTRA
-CFLAGS += -DCONFIG_GNUTLS_EXTRA
-LIBS += -lgnutls-extra
-endif
endif
OBJS += ../src/crypto/crypto_gnutls.o
OBJS_p += ../src/crypto/crypto_gnutls.o
@@ -885,6 +916,9 @@ OBJS += ../src/tls/pkcs8.o
NEED_SHA256=y
NEED_BASE64=y
NEED_TLS_PRF=y
+ifdef CONFIG_TLSV12
+NEED_TLS_PRF_SHA256=y
+endif
NEED_MODEXP=y
NEED_CIPHER=y
CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
@@ -1068,6 +1102,9 @@ SHA256OBJS += ../src/crypto/sha256.o
ifdef CONFIG_INTERNAL_SHA256
SHA256OBJS += ../src/crypto/sha256-internal.o
endif
+ifdef NEED_TLS_PRF_SHA256
+SHA256OBJS += ../src/crypto/sha256-tlsprf.o
+endif
OBJS += $(SHA256OBJS)
endif
@@ -1215,12 +1252,6 @@ OBJS += sme.o
CFLAGS += -DCONFIG_SME
endif
-ifdef CONFIG_CLIENT_MLME
-OBJS += mlme.o
-CFLAGS += -DCONFIG_CLIENT_MLME
-NEED_80211_COMMON=y
-endif
-
ifdef NEED_80211_COMMON
OBJS += ../src/common/ieee802_11_common.o
endif
@@ -1255,6 +1286,7 @@ endif
OBJS += $(SHA1OBJS) $(DESOBJS)
OBJS_p += $(SHA1OBJS)
+OBJS_p += $(SHA256OBJS)
ifdef CONFIG_BGSCAN_SIMPLE
CFLAGS += -DCONFIG_BGSCAN_SIMPLE
@@ -1273,7 +1305,21 @@ CFLAGS += -DCONFIG_BGSCAN
OBJS += bgscan.o
endif
-OBJS_wpa_rm := ctrl_iface.o mlme.o ctrl_iface_unix.o
+ifdef NEED_GAS
+OBJS += ../src/common/gas.o
+OBJS += gas_query.o
+CFLAGS += -DCONFIG_GAS
+NEED_OFFCHANNEL=y
+endif
+
+ifdef NEED_OFFCHANNEL
+OBJS += offchannel.o
+CFLAGS += -DCONFIG_OFFCHANNEL
+endif
+
+OBJS += ../src/drivers/driver_common.o
+
+OBJS_wpa_rm := ctrl_iface.o ctrl_iface_unix.o
OBJS_wpa := $(filter-out $(OBJS_wpa_rm),$(OBJS)) $(OBJS_h) tests/test_wpa.o
ifdef CONFIG_AUTHENTICATOR
OBJS_wpa += tests/link_test.o
@@ -1298,6 +1344,9 @@ OBJS_priv += ../src/utils/common.o
OBJS_priv += ../src/utils/wpa_debug.o
OBJS_priv += ../src/utils/wpabuf.o
OBJS_priv += wpa_priv.o
+ifdef CONFIG_DRIVER_NL80211
+OBJS_priv += ../src/common/ieee802_11_common.o
+endif
ifdef CONFIG_DRIVER_TEST
OBJS_priv += $(SHA1OBJS)
OBJS_priv += $(MD5OBJS)
@@ -1362,15 +1411,17 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
$(Q)$(LDO) $(LDFLAGS) -o wpa_priv $(OBJS_priv) $(LIBS)
@$(E) " LD " $@
-wpa_supplicant: .config $(BCHECK) $(OBJS) $(EXTRA_progs)
+$(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
+
+wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
@$(E) " LD " $@
-eapol_test: .config $(OBJS_t)
+eapol_test: $(OBJS_t)
$(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS)
@$(E) " LD " $@
-preauth_test: .config $(OBJS_t2)
+preauth_test: $(OBJS_t2)
$(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS)
@$(E) " LD " $@
@@ -1422,6 +1473,9 @@ eap_ikev2.so: ../src/eap_peer/eap_ikev2.c ../src/eap_peer/ikev2.c ../src/eap_com
$(Q)$(CC) -c -o $@ $(CFLAGS) $<
@$(E) " CC " $<
+%.service: %.service.in
+ sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
+
wpa_supplicant.exe: wpa_supplicant
mv -f $< $@
wpa_cli.exe: wpa_cli
@@ -1438,11 +1492,8 @@ WINALL=wpa_supplicant.exe wpa_cli.exe wpa_passphrase.exe win_if_list.exe
windows-bin: $(WINALL)
$(STRIP) $(WINALL)
-wpa_gui/Makefile:
- qmake -o wpa_gui/Makefile wpa_gui/wpa_gui.pro
-
-wpa_gui: wpa_gui/Makefile
- $(MAKE) -C wpa_gui
+wpa_gui:
+ @echo "wpa_gui has been removed - see wpa_gui-qt4 for replacement"
wpa_gui-qt4/Makefile:
qmake -o wpa_gui-qt4/Makefile wpa_gui-qt4/wpa_gui.pro
diff --git a/wpa_supplicant/README b/wpa_supplicant/README
index 506a907..4d02f8f 100644
--- a/wpa_supplicant/README
+++ b/wpa_supplicant/README
@@ -138,39 +138,6 @@ Current hardware/software requirements:
default option to start with before falling back to driver specific
interface.
- Host AP driver for Prism2/2.5/3 (development snapshot/v0.2.x)
- (http://hostap.epitest.fi/)
- Driver need to be set in Managed mode ('iwconfig wlan0 mode managed').
- Please note that station firmware version needs to be 1.7.0 or newer
- to work in WPA mode.
-
- Linuxant DriverLoader (http://www.linuxant.com/driverloader/)
- with Windows NDIS driver for your wlan card supporting WPA.
-
- madwifi driver for cards based on Atheros chip set (ar521x)
- (http://sourceforge.net/projects/madwifi/)
- Please note that you will need to modify the wpa_supplicant .config
- file to use the correct path for the madwifi driver root directory
- (CFLAGS += -I../madwifi/wpa line in example defconfig).
-
- Linux ndiswrapper (http://ndiswrapper.sourceforge.net/) with
- Windows NDIS driver.
-
- Broadcom wl.o driver (old version only)
- This is a generic Linux driver for Broadcom IEEE 802.11a/g cards.
- However, it is proprietary driver that is not publicly available
- except for couple of exceptions, mainly Broadcom-based APs/wireless
- routers that use Linux. The driver binary can be downloaded, e.g.,
- from Linksys support site (http://www.linksys.com/support/gpl.asp)
- for Linksys WRT54G. The GPL tarball includes cross-compiler and
- the needed header file, wlioctl.h, for compiling wpa_supplicant.
- This driver support in wpa_supplicant is expected to work also with
- other devices based on Broadcom driver (assuming the driver includes
- client mode support). Please note that the newer Broadcom driver
- ("hybrid Linux driver") supports Linux wireless extensions and does
- not need (or even work) with the specific driver wrapper. Use -Dwext
- with that driver.
-
In theory, any driver that supports Linux wireless extensions can be
used with IEEE 802.1X (i.e., not WPA) when using ap_scan=0 option in
configuration file.
@@ -347,7 +314,7 @@ and a list of available options and additional notes.
The build time configuration can be used to select only the needed
features and limit the binary size and requirements for external
libraries. The main configuration parts are the selection of which
-driver interfaces (e.g., hostap, madwifi, ..) and which authentication
+driver interfaces (e.g., nl80211, wext, ..) and which authentication
methods (e.g., EAP-TLS, EAP-PEAP, ..) are included.
Following build time configuration options are used to control IEEE
@@ -382,21 +349,16 @@ CONFIG_PCSC=y
Following options can be added to .config to select which driver
interfaces are included.
-CONFIG_DRIVER_HOSTAP=y
-CONFIG_DRIVER_MADWIFI=y
+CONFIG_DRIVER_NL80211=y
CONFIG_DRIVER_WEXT=y
-CONFIG_DRIVER_RALINK=y
-CONFIG_DRIVER_BROADCOM=y
CONFIG_DRIVER_BSD=y
CONFIG_DRIVER_NDIS=y
-Following example includes all features and driver interfaces that are
-included in the wpa_supplicant package:
+Following example includes some more features and driver interfaces that
+are included in the wpa_supplicant package:
-CONFIG_DRIVER_HOSTAP=y
-CONFIG_DRIVER_MADWIFI=y
+CONFIG_DRIVER_NL80211=y
CONFIG_DRIVER_WEXT=y
-CONFIG_DRIVER_BROADCOM=y
CONFIG_DRIVER_BSD=y
CONFIG_DRIVER_NDIS=y
CONFIG_IEEE8021X_EAPOL=y
@@ -489,12 +451,7 @@ options:
-N = start describing new interface
drivers:
- hostap = Host AP driver (Intersil Prism2/2.5/3) [default]
- (this can also be used with Linuxant DriverLoader)
- madwifi = MADWIFI 802.11 support (Atheros, etc.) (deprecated; use wext)
wext = Linux wireless extensions (generic)
- ralink = Ralink Client driver
- broadcom = Broadcom wl.o driver
wired = wpa_supplicant wired Ethernet driver
roboswitch = wpa_supplicant Broadcom switch driver
bsd = BSD 802.11 support (Atheros, etc.)
@@ -527,15 +484,15 @@ separated with -N argument. As an example, following command would
start wpa_supplicant for two interfaces:
wpa_supplicant \
- -c wpa1.conf -i wlan0 -D hostap -N \
- -c wpa2.conf -i ath0 -D madwifi
+ -c wpa1.conf -i wlan0 -D nl80211 -N \
+ -c wpa2.conf -i wlan1 -D wext
If the interface is added in a Linux bridge (e.g., br0), the bridge
interface needs to be configured to wpa_supplicant in addition to the
main interface:
-wpa_supplicant -cw.conf -Dmadwifi -iath0 -bbr0
+wpa_supplicant -cw.conf -Dwext -iwlan0 -bbr0
Configuration file
diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P
index 0c1ca03..db6e4ae 100644
--- a/wpa_supplicant/README-P2P
+++ b/wpa_supplicant/README-P2P
@@ -101,7 +101,7 @@ Flush P2P peer table and state.
Group Formation
-p2p_prov_disc <peer device address> <display|keypad|pbc>
+p2p_prov_disc <peer device address> <display|keypad|pbc> [join]
Send P2P provision discovery request to the specified peer. The
parameters for this command are the P2P device address of the peer and
@@ -110,7 +110,11 @@ the desired configuration method. For example, "p2p_prov_disc
us and "p2p_prov_disc 02:01:02:03:04:05 keypad" would request the peer
to enter a PIN that we display.
-p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
+The optional "join" parameter can be used to indicate that this command
+is requesting an already running GO to prepare for a new client. This is
+mainly used with "display" to request it to display a PIN.
+
+p2p_connect <peer device address> <pbc|pin|PIN#> [display|keypad]
[persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>]
Start P2P group formation with a discovered P2P peer. This includes
@@ -121,10 +125,9 @@ The <pbc|pin|PIN#> parameter specifies the WPS provisioning
method. "pbc" string starts pushbutton method, "pin" string start PIN
method using an automatically generated PIN (which will be returned as
the command return code), PIN# means that a pre-selected PIN can be
-used (e.g., 12345670). [label|display|keypad] is used with PIN method
-to specify which PIN is used (label=PIN from local label,
-display=dynamically generated random PIN from local display,
-keypad=PIN entered from peer device label or display). "persistent"
+used (e.g., 12345670). [display|keypad] is used with PIN method
+to specify which PIN is used (display=dynamically generated random PIN
+from local display, keypad=PIN entered from peer display). "persistent"
parameter can be used to request a persistent group to be formed.
"join" indicates that this is a command to join an existing group as a
diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS
index 313e873..bf75cb4 100644
--- a/wpa_supplicant/README-WPS
+++ b/wpa_supplicant/README-WPS
@@ -127,6 +127,11 @@ This starts the WPS negotiation in the same way as above with the
generated PIN.
+If a random PIN is needed for a user interface, "wpa_cli wps_pin get"
+can be used to generate a new PIN without starting WPS negotiation.
+This random PIN can then be passed as an argument to another wps_pin
+call when the actual operation should be started.
+
If the client design wants to support optional WPS PBC mode, this can
be enabled by either a physical button in the client device or a
virtual button in the user interface. The PBC operation requires that
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 6d9037a..1386d0c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -23,16 +23,13 @@
#include "ap/hostapd.h"
#include "ap/ap_config.h"
#include "ap/ap_drv_ops.h"
-#if defined (NEED_AP_MLME) || defined (ANDROID_BRCM_P2P_PATCH)
+#ifdef NEED_AP_MLME
#include "ap/ieee802_11.h"
#endif /* NEED_AP_MLME */
#include "ap/beacon.h"
#include "ap/ieee802_1x.h"
#include "ap/wps_hostapd.h"
#include "ap/ctrl_iface_ap.h"
-#include "eap_common/eap_defs.h"
-#include "eap_server/eap_methods.h"
-#include "eap_common/eap_wsc_common.h"
#include "wps/wps.h"
#include "common/ieee802_11_defs.h"
#include "config_ssid.h"
@@ -56,10 +53,6 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
{
struct hostapd_bss_config *bss = &conf->bss[0];
int pairwise;
-#ifdef CONFIG_IEEE80211N
- struct hostapd_hw_modes *modes;
- u16 num_modes, flags;
-#endif /* CONFIG_IEEE80211N */
conf->driver = wpa_s->driver;
@@ -87,24 +80,35 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_IEEE80211N
/*
- * Enable HT20 if the driver supports it, by setting conf->ieee80211n.
+ * Enable HT20 if the driver supports it, by setting conf->ieee80211n
+ * and a mask of allowed capabilities within conf->ht_capab.
* Using default config settings for: conf->ht_op_mode_fixed,
- * conf->ht_capab, conf->secondary_channel, conf->require_ht
+ * conf->secondary_channel, conf->require_ht
*/
- modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
- if (modes) {
+ if (wpa_s->hw.modes) {
struct hostapd_hw_modes *mode = NULL;
int i;
- for (i = 0; i < num_modes; i++) {
- if (modes[i].mode == conf->hw_mode) {
- mode = &modes[i];
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
+ if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
+ mode = &wpa_s->hw.modes[i];
break;
}
}
- if (mode && mode->ht_capab)
+ if (mode && mode->ht_capab) {
conf->ieee80211n = 1;
- ieee80211_sta_free_hw_features(modes, num_modes);
- modes = NULL;
+
+ /*
+ * white-list capabilities that won't cause issues
+ * to connecting stations, while leaving the current
+ * capabilities intact (currently disabled SMPS).
+ */
+ conf->ht_capab |= mode->ht_capab &
+ (HT_CAP_INFO_GREEN_FIELD |
+ HT_CAP_INFO_SHORT_GI20MHZ |
+ HT_CAP_INFO_SHORT_GI40MHZ |
+ HT_CAP_INFO_RX_STBC_MASK |
+ HT_CAP_INFO_MAX_AMSDU_SIZE);
+ }
}
#endif /* CONFIG_IEEE80211N */
@@ -134,6 +138,8 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
}
conf->supported_rates = list;
}
+
+ bss->isolate = !wpa_s->conf->p2p_intra_bss;
#endif /* CONFIG_P2P */
if (ssid->ssid_len == 0) {
@@ -145,6 +151,9 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
bss->ssid.ssid_len = ssid->ssid_len;
bss->ssid.ssid_set = 1;
+ if (ssid->auth_alg)
+ bss->auth_algs = ssid->auth_alg;
+
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
bss->wpa = ssid->proto;
bss->wpa_key_mgmt = ssid->key_mgmt;
@@ -158,6 +167,22 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
return -1;
os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
bss->ssid.wpa_psk->group = 1;
+ } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
+ ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
+ struct hostapd_wep_keys *wep = &bss->ssid.wep;
+ int i;
+ for (i = 0; i < NUM_WEP_KEYS; i++) {
+ if (ssid->wep_key_len[i] == 0)
+ continue;
+ wep->key[i] = os_malloc(ssid->wep_key_len[i]);
+ if (wep->key[i] == NULL)
+ return -1;
+ os_memcpy(wep->key[i], ssid->wep_key[i],
+ ssid->wep_key_len[i]);
+ wep->len[i] = ssid->wep_key_len[i];
+ }
+ wep->idx = ssid->wep_tx_keyidx;
+ wep->keys_set = 1;
}
/* Select group cipher based on the enabled pairwise cipher suites */
@@ -179,18 +204,45 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
else if (bss->wpa)
bss->ssid.security_policy = SECURITY_WPA_PSK;
else if (bss->ieee802_1x) {
+ int cipher = WPA_CIPHER_NONE;
bss->ssid.security_policy = SECURITY_IEEE_802_1X;
bss->ssid.wep.default_len = bss->default_wep_key_len;
- } else if (bss->ssid.wep.keys_set)
+ if (bss->default_wep_key_len)
+ cipher = bss->default_wep_key_len >= 13 ?
+ WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
+ bss->wpa_group = cipher;
+ bss->wpa_pairwise = cipher;
+ bss->rsn_pairwise = cipher;
+ } else if (bss->ssid.wep.keys_set) {
+ int cipher = WPA_CIPHER_WEP40;
+ if (bss->ssid.wep.len[0] >= 13)
+ cipher = WPA_CIPHER_WEP104;
bss->ssid.security_policy = SECURITY_STATIC_WEP;
- else
+ bss->wpa_group = cipher;
+ bss->wpa_pairwise = cipher;
+ bss->rsn_pairwise = cipher;
+ } else {
bss->ssid.security_policy = SECURITY_PLAINTEXT;
+ bss->wpa_group = WPA_CIPHER_NONE;
+ bss->wpa_pairwise = WPA_CIPHER_NONE;
+ bss->rsn_pairwise = WPA_CIPHER_NONE;
+ }
#ifdef CONFIG_WPS
/*
- * Enable WPS by default, but require user interaction to actually use
- * it. Only the internal Registrar is supported.
+ * Enable WPS by default for open and WPA/WPA2-Personal network, but
+ * require user interaction to actually use it. Only the internal
+ * Registrar is supported.
*/
+ if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
+ bss->ssid.security_policy != SECURITY_PLAINTEXT)
+ goto no_wps;
+#ifdef CONFIG_WPS2
+ if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
+ (!(pairwise & WPA_CIPHER_CCMP) || !(bss->wpa & 2)))
+ goto no_wps; /* WPS2 does not allow WPA/TKIP-only
+ * configuration */
+#endif /* CONFIG_WPS2 */
bss->eap_server = 1;
bss->wps_state = 2;
bss->ap_setup_locked = 2;
@@ -215,6 +267,7 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
else
os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
+no_wps:
#endif /* CONFIG_WPS */
if (wpa_s->max_stations &&
@@ -275,9 +328,9 @@ static void ap_wps_event_cb(void *ctx, enum wps_event event,
static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
- int authorized)
+ int authorized, const u8 *p2p_dev_addr)
{
- wpas_notify_sta_authorized(ctx, mac_addr, authorized);
+ wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
}
@@ -301,12 +354,12 @@ static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
}
-static int ap_probe_req_rx(void *ctx, const u8 *addr, const u8 *ie,
- size_t ie_len)
+static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
+ const u8 *bssid, const u8 *ie, size_t ie_len)
{
#ifdef CONFIG_P2P
struct wpa_supplicant *wpa_s = ctx;
- return wpas_p2p_probe_req_rx(wpa_s, addr, ie, ie_len);
+ return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len);
#else /* CONFIG_P2P */
return 0;
#endif /* CONFIG_P2P */
@@ -371,6 +424,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
}
params.freq = ssid->frequency;
+ params.wpa_proto = ssid->proto;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
else
@@ -395,7 +449,6 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
if (ssid->mode == WPAS_MODE_P2P_GO ||
ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
params.p2p = 1;
- wpa_drv_set_intra_bss(wpa_s, wpa_s->conf->p2p_intra_bss);
#endif /* CONFIG_P2P */
if (wpa_s->parent->set_ap_uapsd)
@@ -412,6 +465,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
if (hapd_iface == NULL)
return -1;
hapd_iface->owner = wpa_s;
+ hapd_iface->drv_flags = wpa_s->drv_flags;
+ hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
if (conf == NULL) {
@@ -419,6 +474,11 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
return -1;
}
+ if (params.uapsd > 0) {
+ conf->bss->wmm_enabled = 1;
+ conf->bss->wmm_uapsd = 1;
+ }
+
if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
wpa_printf(MSG_ERROR, "Failed to create AP configuration");
wpa_supplicant_ap_deinit(wpa_s);
@@ -451,10 +511,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
}
hapd_iface->bss[i]->msg_ctx = wpa_s;
-#ifdef ANDROID_BRCM_P2P_PATCH
- /* Sending the event to parent is required as SSL listens on parent ctrl iface */
hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
-#endif
hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
@@ -490,14 +547,6 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
wpa_supplicant_ap_deinit(wpa_s);
return -1;
}
-
-#ifdef ANDROID_BRCM_P2P_PATCH
- if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
- "report received Probe Request frames");
- return -1;
- }
-#endif
return 0;
}
@@ -537,23 +586,38 @@ void ap_tx_status(void *ctx, const u8 *addr,
}
-void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len)
+void ap_eapol_tx_status(void *ctx, const u8 *dst,
+ const u8 *data, size_t len, int ack)
{
#ifdef NEED_AP_MLME
struct wpa_supplicant *wpa_s = ctx;
- const struct ieee80211_hdr *hdr =
- (const struct ieee80211_hdr *) frame;
- u16 fc = le_to_host16(hdr->frame_control);
- ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], hdr->addr2,
- (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
- (WLAN_FC_TODS | WLAN_FC_FROMDS));
+ hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
+#endif /* NEED_AP_MLME */
+}
+
+
+void ap_client_poll_ok(void *ctx, const u8 *addr)
+{
+#ifdef NEED_AP_MLME
+ struct wpa_supplicant *wpa_s = ctx;
+ if (wpa_s->ap_iface)
+ hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
+#endif /* NEED_AP_MLME */
+}
+
+
+void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
+{
+#ifdef NEED_AP_MLME
+ struct wpa_supplicant *wpa_s = ctx;
+ ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
#endif /* NEED_AP_MLME */
}
void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
{
-#if defined (NEED_AP_MLME) || defined (ANDROID_BRCM_P2P_PATCH)
+#ifdef NEED_AP_MLME
struct wpa_supplicant *wpa_s = ctx;
struct hostapd_frame_info fi;
os_memset(&fi, 0, sizeof(fi));
@@ -561,7 +625,7 @@ void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
fi.ssi_signal = rx_mgmt->ssi_signal;
ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
rx_mgmt->frame_len, &fi);
-#endif /* defined (NEED_AP_MLME) || defined (ANDROID_BRCM_P2P_PATCH) */
+#endif /* NEED_AP_MLME */
}
@@ -648,7 +712,7 @@ int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
if (pin == NULL) {
unsigned int rpin = wps_generate_pin();
- ret_len = os_snprintf(buf, buflen, "%d", rpin);
+ ret_len = os_snprintf(buf, buflen, "%08d", rpin);
pin = buf;
} else
ret_len = os_snprintf(buf, buflen, "%s", pin);
@@ -709,7 +773,7 @@ const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
return NULL;
hapd = wpa_s->ap_iface->bss[0];
pin = wps_generate_pin();
- os_snprintf(pin_txt, sizeof(pin_txt), "%u", pin);
+ os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
os_free(hapd->conf->ap_pin);
hapd->conf->ap_pin = os_strdup(pin_txt);
if (hapd->conf->ap_pin == NULL)
@@ -849,7 +913,9 @@ int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
struct wpa_ssid *ssid = wpa_s->current_ssid;
struct hostapd_data *hapd;
- if (ssid == NULL || wpa_s->ap_iface == NULL)
+ if (ssid == NULL || wpa_s->ap_iface == NULL ||
+ ssid->mode == WPAS_MODE_INFRA ||
+ ssid->mode == WPAS_MODE_IBSS)
return -1;
#ifdef CONFIG_P2P
@@ -860,8 +926,10 @@ int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
P2P_GROUP_FORMATION;
#endif /* CONFIG_P2P */
- ieee802_11_set_beacons(iface);
hapd = iface->bss[0];
+ if (hapd->drv_priv == NULL)
+ return -1;
+ ieee802_11_set_beacons(iface);
hostapd_set_ap_wps_ie(hapd);
return 0;
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
index b913be3..aa4c362 100644
--- a/wpa_supplicant/ap.h
+++ b/wpa_supplicant/ap.h
@@ -41,7 +41,10 @@ int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
size_t buflen, int verbose);
void ap_tx_status(void *ctx, const u8 *addr,
const u8 *buf, size_t len, int ack);
-void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len);
+void ap_eapol_tx_status(void *ctx, const u8 *dst,
+ const u8 *data, size_t len, int ack);
+void ap_client_poll_ok(void *ctx, const u8 *addr);
+void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds);
void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt);
void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok);
int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c
index ee79511..5385cce 100644
--- a/wpa_supplicant/bgscan_learn.c
+++ b/wpa_supplicant/bgscan_learn.c
@@ -355,20 +355,19 @@ static int bgscan_learn_get_params(struct bgscan_learn_data *data,
static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
{
struct hostapd_hw_modes *modes;
- u16 num_modes, flags;
int i, j, *freqs = NULL, *n;
size_t count = 0;
- modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
- if (!modes)
+ modes = wpa_s->hw.modes;
+ if (modes == NULL)
return NULL;
- for (i = 0; i < num_modes; i++) {
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
for (j = 0; j < modes[i].num_channels; j++) {
if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED)
continue;
n = os_realloc(freqs, (count + 2) * sizeof(int));
- if (!n)
+ if (n == NULL)
continue;
freqs = n;
@@ -376,10 +375,7 @@ static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
count++;
freqs[count] = 0;
}
- os_free(modes[i].channels);
- os_free(modes[i].rates);
}
- os_free(modes);
return freqs;
}
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 5b48951..078e22d 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -50,6 +50,15 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
" SSID '%s'", bss->id, MAC2STR(bss->bssid),
wpa_ssid_txt(bss->ssid, bss->ssid_len));
wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
+#ifdef CONFIG_INTERWORKING
+ wpabuf_free(bss->anqp_venue_name);
+ wpabuf_free(bss->anqp_network_auth_type);
+ wpabuf_free(bss->anqp_roaming_consortium);
+ wpabuf_free(bss->anqp_ip_addr_type_availability);
+ wpabuf_free(bss->anqp_nai_realm);
+ wpabuf_free(bss->anqp_3gpp);
+ wpabuf_free(bss->anqp_domain_name);
+#endif /* CONFIG_INTERWORKING */
os_free(bss);
}
@@ -93,6 +102,55 @@ static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src)
}
+static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+{
+ struct wpa_ssid *ssid;
+
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+ if (ssid->ssid == NULL || ssid->ssid_len == 0)
+ continue;
+ if (ssid->ssid_len == bss->ssid_len &&
+ os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_bss *bss;
+
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+ if (!wpa_bss_known(wpa_s, bss)) {
+ wpa_bss_remove(wpa_s, bss);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+
+static void wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
+{
+ /*
+ * Remove the oldest entry that does not match with any configured
+ * network.
+ */
+ if (wpa_bss_remove_oldest_unknown(wpa_s) == 0)
+ return;
+
+ /*
+ * Remove the oldest entry since no better candidate for removal was
+ * found.
+ */
+ wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss,
+ struct wpa_bss, list));
+}
+
+
static void wpa_bss_add(struct wpa_supplicant *wpa_s,
const u8 *ssid, size_t ssid_len,
struct wpa_scan_res *res)
@@ -118,11 +176,8 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
" SSID '%s'",
bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
- if (wpa_s->num_bss > wpa_s->conf->bss_max_count) {
- /* Remove the oldest entry */
- wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss,
- struct wpa_bss, list));
- }
+ if (wpa_s->num_bss > wpa_s->conf->bss_max_count)
+ wpa_bss_remove_oldest(wpa_s);
}
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index 992b9c0..bb19f49 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -23,6 +23,7 @@ struct wpa_scan_res;
#define WPA_BSS_LEVEL_DBM BIT(3)
#define WPA_BSS_AUTHENTICATED BIT(4)
#define WPA_BSS_ASSOCIATED BIT(5)
+#define WPA_BSS_ANQP_FETCH_TRIED BIT(6)
/**
* struct wpa_bss - BSS table
@@ -65,6 +66,15 @@ struct wpa_bss {
int level;
u64 tsf;
struct os_time last_update;
+#ifdef CONFIG_INTERWORKING
+ struct wpabuf *anqp_venue_name;
+ struct wpabuf *anqp_network_auth_type;
+ struct wpabuf *anqp_roaming_consortium;
+ struct wpabuf *anqp_ip_addr_type_availability;
+ struct wpabuf *anqp_nai_realm;
+ struct wpabuf *anqp_3gpp;
+ struct wpabuf *anqp_domain_name;
+#endif /* CONFIG_INTERWORKING */
size_t ie_len;
size_t beacon_ie_len;
/* followed by ie_len octets of IEs */
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 19c810b..9cd26dd 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1371,6 +1371,90 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data,
#endif /* NO_CONFIG_WRITE */
+#ifdef CONFIG_P2P
+
+static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ const char *pos;
+ u8 *buf, *n, addr[ETH_ALEN];
+ size_t count;
+
+ buf = NULL;
+ count = 0;
+
+ pos = value;
+ while (pos && *pos) {
+ while (*pos == ' ')
+ pos++;
+
+ if (hwaddr_aton(pos, addr)) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid "
+ "p2p_client_list address '%s'.",
+ line, value);
+ /* continue anyway */
+ } else {
+ n = os_realloc(buf, (count + 1) * ETH_ALEN);
+ if (n == NULL) {
+ os_free(buf);
+ return -1;
+ }
+ buf = n;
+ os_memcpy(buf + count * ETH_ALEN, addr, ETH_ALEN);
+ count++;
+ wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
+ addr, ETH_ALEN);
+ }
+
+ pos = os_strchr(pos, ' ');
+ }
+
+ os_free(ssid->p2p_client_list);
+ ssid->p2p_client_list = buf;
+ ssid->num_p2p_clients = count;
+
+ return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ char *value, *end, *pos;
+ int res;
+ size_t i;
+
+ if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
+ return NULL;
+
+ value = os_malloc(20 * ssid->num_p2p_clients);
+ if (value == NULL)
+ return NULL;
+ pos = value;
+ end = value + 20 * ssid->num_p2p_clients;
+
+ for (i = 0; i < ssid->num_p2p_clients; i++) {
+ res = os_snprintf(pos, end - pos, MACSTR " ",
+ MAC2STR(ssid->p2p_client_list +
+ i * ETH_ALEN));
+ if (res < 0 || res >= end - pos) {
+ os_free(value);
+ return NULL;
+ }
+ pos += res;
+ }
+
+ if (pos > value)
+ pos[-1] = '\0';
+
+ return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
+#endif /* CONFIG_P2P */
+
/* Helper macros for network block parser */
#ifdef OFFSET
@@ -1544,6 +1628,9 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(frequency, 0, 10000) },
{ INT(wpa_ptk_rekey) },
{ STR(bgscan) },
+#ifdef CONFIG_P2P
+ { FUNC(p2p_client_list) },
+#endif /* CONFIG_P2P */
};
#ifdef WPA_UNICODE_SSID
@@ -1719,6 +1806,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
os_free(ssid->scan_freq);
os_free(ssid->freq_list);
os_free(ssid->bgscan);
+ os_free(ssid->p2p_client_list);
os_free(ssid);
}
@@ -1768,6 +1856,12 @@ void wpa_config_free(struct wpa_config *config)
os_free(config->config_methods);
os_free(config->p2p_ssid_postfix);
os_free(config->pssid);
+ os_free(config->home_realm);
+ os_free(config->home_username);
+ os_free(config->home_password);
+ os_free(config->home_ca_cert);
+ os_free(config->home_imsi);
+ os_free(config->home_milenage);
os_free(config);
}
@@ -1951,6 +2045,27 @@ int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
}
+int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
+ const char *value)
+{
+ size_t len;
+ char *buf;
+ int ret;
+
+ len = os_strlen(value);
+ buf = os_malloc(len + 3);
+ if (buf == NULL)
+ return -1;
+ buf[0] = '"';
+ os_memcpy(buf + 1, value, len);
+ buf[len + 1] = '"';
+ buf[len + 2] = '\0';
+ ret = wpa_config_set(ssid, var, buf, 0);
+ os_free(buf);
+ return ret;
+}
+
+
/**
* wpa_config_get_all - Get all options from network configuration
* @ssid: Pointer to network configuration data
@@ -2215,6 +2330,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
config->max_num_sta = DEFAULT_MAX_NUM_STA;
+ config->access_network_type = DEFAULT_ACCESS_NETWORK_TYPE;
if (ctrl_interface)
config->ctrl_interface = os_strdup(ctrl_interface);
@@ -2423,6 +2539,20 @@ static int wpa_config_process_sec_device_type(
#endif /* CONFIG_P2P */
+static int wpa_config_process_hessid(
+ const struct global_parse_data *data,
+ struct wpa_config *config, int line, const char *pos)
+{
+ if (hwaddr_aton2(pos, config->hessid) < 0) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid hessid '%s'",
+ line, pos);
+ return -1;
+ }
+
+ return 0;
+}
+
+
#ifdef OFFSET
#undef OFFSET
#endif /* OFFSET */
@@ -2487,7 +2617,16 @@ static const struct global_parse_data global_fields[] = {
{ INT(bss_expiration_scan_count), 0 },
{ INT_RANGE(filter_ssids, 0, 1), 0 },
{ INT(max_num_sta), 0 },
- { INT_RANGE(disassoc_low_ack, 0, 1), 0 }
+ { INT_RANGE(disassoc_low_ack, 0, 1), 0 },
+ { STR(home_realm), 0 },
+ { STR(home_username), 0 },
+ { STR(home_password), 0 },
+ { STR(home_ca_cert), 0 },
+ { STR(home_imsi), 0 },
+ { STR(home_milenage), 0 },
+ { INT_RANGE(interworking, 0, 1), 0 },
+ { FUNC(hessid), 0 },
+ { INT_RANGE(access_network_type, 0, 15), 0 }
};
#undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 10abdad..f9e5043 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -28,6 +28,7 @@
#define DEFAULT_BSS_EXPIRATION_AGE 180
#define DEFAULT_BSS_EXPIRATION_SCAN_COUNT 2
#define DEFAULT_MAX_NUM_STA 128
+#define DEFAULT_ACCESS_NETWORK_TYPE 15
#include "config_ssid.h"
#include "wps/wps.h"
@@ -123,7 +124,7 @@ struct wpa_config {
* If this is specified, %wpa_supplicant will open a control interface
* that is available for external programs to manage %wpa_supplicant.
* The meaning of this string depends on which control interface
- * mechanism is used. For all cases, the existance of this parameter
+ * mechanism is used. For all cases, the existence of this parameter
* in configuration is used to determine whether the control interface
* is enabled.
*
@@ -376,7 +377,10 @@ struct wpa_config {
* stations in the group. As a P2P client, this means no GO seen in
* scan results. The maximum idle time is specified in seconds with 0
* indicating no time limit, i.e., the P2P group remains in active
- * state indefinitely until explicitly removed.
+ * state indefinitely until explicitly removed. As a P2P client, the
+ * maximum idle time of P2P_MAX_CLIENT_IDLE seconds is enforced, i.e.,
+ * this parameter is mainly meant for GO use and for P2P client, it can
+ * only be used to reduce the default timeout to smaller value.
*/
unsigned int p2p_group_idle;
@@ -426,6 +430,60 @@ struct wpa_config {
* disassoc_low_ack - Disassocicate stations with massive packet loss
*/
int disassoc_low_ack;
+
+ /**
+ * interworking - Whether Interworking (IEEE 802.11u) is enabled
+ */
+ int interworking;
+
+ /**
+ * access_network_type - Access Network Type
+ *
+ * When Interworking is enabled, scans will be limited to APs that
+ * advertise the specified Access Network Type (0..15; with 15
+ * indicating wildcard match).
+ */
+ int access_network_type;
+
+ /**
+ * hessid - Homogenous ESS identifier
+ *
+ * If this is set (any octet is non-zero), scans will be used to
+ * request response only from BSSes belonging to the specified
+ * Homogeneous ESS. This is used only if interworking is enabled.
+ */
+ u8 hessid[ETH_ALEN];
+
+ /**
+ * home_realm - Home Realm for Interworking
+ */
+ char *home_realm;
+
+ /**
+ * home_username - Username for Interworking network selection
+ */
+ char *home_username;
+
+ /**
+ * home_password - Password for Interworking network selection
+ */
+ char *home_password;
+
+ /**
+ * home_ca_cert - CA certificate for Interworking network selection
+ */
+ char *home_ca_cert;
+
+ /**
+ * home_imsi - IMSI in <MCC> | <MNC> | '-' | <MSIN> format
+ */
+ char *home_imsi;
+
+ /**
+ * home_milenage - Milenage parameters for SIM/USIM simulator in
+ * <Ki>:<OPc>:<SQN> format
+ */
+ char *home_milenage;
};
@@ -442,6 +500,8 @@ int wpa_config_remove_network(struct wpa_config *config, int id);
void wpa_config_set_network_defaults(struct wpa_ssid *ssid);
int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
int line);
+int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
+ const char *value);
char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys);
char * wpa_config_get(struct wpa_ssid *ssid, const char *var);
char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var);
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 2d5fdd6..f3a7291 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -104,9 +104,7 @@ static int wpa_config_validate_network(struct wpa_ssid *ssid, int line)
wpa_config_update_psk(ssid);
}
- if ((ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_PSK_SHA256)) &&
- !ssid->psk_set) {
+ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set) {
wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key "
"management, but no PSK configured.", line);
errors++;
@@ -495,6 +493,18 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
}
+#ifdef CONFIG_P2P
+static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
+{
+ char *value = wpa_config_get(ssid, "p2p_client_list");
+ if (value == NULL)
+ return;
+ fprintf(f, "\tp2p_client_list=%s\n", value);
+ os_free(value);
+}
+#endif /* CONFIG_P2P */
+
+
static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
{
int i;
@@ -569,6 +579,9 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
INT(ieee80211w);
#endif /* CONFIG_IEEE80211W */
STR(id_str);
+#ifdef CONFIG_P2P
+ write_p2p_client_list(f, ssid);
+#endif /* CONFIG_P2P */
#undef STR
#undef INT
@@ -649,7 +662,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
buf = wps_dev_type_bin2str(config->device_type,
_buf, sizeof(_buf));
- fprintf(f, "device_type=%s\n", buf);
+ if (os_strcmp(buf, "0-00000000-0") != 0)
+ fprintf(f, "device_type=%s\n", buf);
}
if (WPA_GET_BE32(config->os_version))
fprintf(f, "os_version=%08x\n",
@@ -703,6 +717,27 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
fprintf(f, "max_num_sta=%u\n", config->max_num_sta);
if (config->disassoc_low_ack)
fprintf(f, "disassoc_low_ack=%u\n", config->disassoc_low_ack);
+#ifdef CONFIG_INTERWORKING
+ if (config->home_realm)
+ fprintf(f, "home_realm=%s\n", config->home_realm);
+ if (config->home_username)
+ fprintf(f, "home_username=%s\n", config->home_username);
+ if (config->home_password)
+ fprintf(f, "home_password=%s\n", config->home_password);
+ if (config->home_ca_cert)
+ fprintf(f, "home_ca_cert=%s\n", config->home_ca_cert);
+ if (config->home_imsi)
+ fprintf(f, "home_imsi=%s\n", config->home_imsi);
+ if (config->home_milenage)
+ fprintf(f, "home_milenage=%s\n", config->home_milenage);
+ if (config->interworking)
+ fprintf(f, "interworking=%u\n", config->interworking);
+ if (!is_zero_ether_addr(config->hessid))
+ fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid));
+ if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE)
+ fprintf(f, "access_network_type=%d\n",
+ config->access_network_type);
+#endif /* CONFIG_INTERWORKING */
}
#endif /* CONFIG_NO_CONFIG_WRITE */
@@ -731,6 +766,9 @@ int wpa_config_write(const char *name, struct wpa_config *config)
for (ssid = config->ssid; ssid; ssid = ssid->next) {
if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary)
continue; /* do not save temporary networks */
+ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
+ !ssid->passphrase)
+ continue; /* do not save invalid network */
fprintf(f, "\nnetwork={\n");
wpa_config_write_network(f, ssid);
fprintf(f, "}\n");
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 8419f43..8a47c0b 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -387,6 +387,20 @@ struct wpa_ssid {
int *freq_list;
/**
+ * p2p_client_list - List of P2P Clients in a persistent group (GO)
+ *
+ * This is a list of P2P Clients (P2P Device Address) that have joined
+ * the persistent group. This is maintained on the GO for persistent
+ * group entries (disabled == 2).
+ */
+ u8 *p2p_client_list;
+
+ /**
+ * num_p2p_clients - Number of entries in p2p_client_list
+ */
+ size_t num_p2p_clients;
+
+ /**
* p2p_group - Network generated as a P2P group (used internally)
*/
int p2p_group;
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index ea3a2ac..5fb2580 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -350,9 +350,7 @@ static struct wpa_ssid * wpa_config_read_network(HKEY hk, const TCHAR *netw,
wpa_config_update_psk(ssid);
}
- if ((ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_PSK_SHA256)) &&
- !ssid->psk_set) {
+ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set) {
wpa_printf(MSG_ERROR, "WPA-PSK accepted for key management, "
"but no PSK configured for network '" TSTR "'.",
netw);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index e05602c..522472f 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -38,7 +38,9 @@
#include "bss.h"
#include "scan.h"
#include "ctrl_iface.h"
+#include "interworking.h"
#include "blacklist.h"
+#include "wpas_glue.h"
extern struct wpa_driver_ops *wpa_drivers[];
@@ -48,6 +50,76 @@ static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
char *buf, int len);
+static int pno_start(struct wpa_supplicant *wpa_s)
+{
+ int ret;
+ size_t i, num_ssid;
+ struct wpa_ssid *ssid;
+ struct wpa_driver_scan_params params;
+
+ if (wpa_s->pno)
+ return 0;
+
+ os_memset(&params, 0, sizeof(params));
+
+ num_ssid = 0;
+ ssid = wpa_s->conf->ssid;
+ while (ssid) {
+ if (!ssid->disabled)
+ num_ssid++;
+ ssid = ssid->next;
+ }
+ if (num_ssid > WPAS_MAX_SCAN_SSIDS) {
+ wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
+ "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid);
+ num_ssid = WPAS_MAX_SCAN_SSIDS;
+ }
+
+ if (num_ssid == 0) {
+ wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
+ return -1;
+ }
+
+ params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) *
+ num_ssid);
+ if (params.filter_ssids == NULL)
+ return -1;
+ i = 0;
+ ssid = wpa_s->conf->ssid;
+ while (ssid) {
+ if (!ssid->disabled) {
+ params.ssids[i].ssid = ssid->ssid;
+ params.ssids[i].ssid_len = ssid->ssid_len;
+ params.num_ssids++;
+ os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
+ ssid->ssid_len);
+ params.filter_ssids[i].ssid_len = ssid->ssid_len;
+ params.num_filter_ssids++;
+ i++;
+ if (i == num_ssid)
+ break;
+ }
+ ssid = ssid->next;
+ }
+
+ ret = wpa_drv_sched_scan(wpa_s, &params, 10 * 1000);
+ os_free(params.filter_ssids);
+ if (ret == 0)
+ wpa_s->pno = 1;
+ return ret;
+}
+
+
+static int pno_stop(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->pno) {
+ wpa_s->pno = 0;
+ return wpa_drv_stop_sched_scan(wpa_s);
+ }
+ return 0;
+}
+
+
static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
char *cmd)
{
@@ -126,6 +198,11 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
ret = -1;
wpa_tdls_enable(wpa_s->wpa, !disabled);
#endif /* CONFIG_TDLS */
+ } else if (os_strcasecmp(cmd, "pno") == 0) {
+ if (atoi(value))
+ ret = pno_start(wpa_s);
+ else
+ ret = pno_stop(wpa_s);
} else {
value[-1] = '=';
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -209,6 +286,7 @@ static int wpa_supplicant_ctrl_iface_tdls_discover(
struct wpa_supplicant *wpa_s, char *addr)
{
u8 peer[ETH_ALEN];
+ int ret;
if (hwaddr_aton(addr, peer)) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
@@ -219,7 +297,12 @@ static int wpa_supplicant_ctrl_iface_tdls_discover(
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
MAC2STR(peer));
- return wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
+ if (wpa_tdls_is_external_setup(wpa_s->wpa))
+ ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
+ else
+ ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
+
+ return ret;
}
@@ -239,8 +322,13 @@ static int wpa_supplicant_ctrl_iface_tdls_setup(
MAC2STR(peer));
ret = wpa_tdls_reneg(wpa_s->wpa, peer);
- if (ret)
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
+ if (ret) {
+ if (wpa_tdls_is_external_setup(wpa_s->wpa))
+ ret = wpa_tdls_start(wpa_s->wpa, peer);
+ else
+ ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
+ }
+
return ret;
}
@@ -259,7 +347,8 @@ static int wpa_supplicant_ctrl_iface_tdls_teardown(
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
MAC2STR(peer));
- return wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
+ return wpa_tdls_teardown_link(wpa_s->wpa, peer,
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
}
#endif /* CONFIG_TDLS */
@@ -303,9 +392,7 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_AP
u8 *_p2p_dev_addr = NULL;
#endif /* CONFIG_AP */
-#ifdef ANDROID_BRCM_P2P_PATCH
- struct wpa_supplicant *iface;
-#endif
+
if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
_bssid = NULL;
#ifdef CONFIG_P2P
@@ -324,17 +411,7 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
return -1;
}
-#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
- if (iface->ap_iface){
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: iface 0x%08x wpa_s->ap_iface %p", (u32)iface, iface->ap_iface);
- wpa_supplicant_ap_wps_pbc(iface, _bssid, _p2p_dev_addr);
- return 0;
- }
- else
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: ap_iface is not set iface 0x%08x", (u32)iface);
- }
-#elif defined CONFIG_AP
+#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
#endif /* CONFIG_AP */
@@ -351,35 +428,22 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
char *pin;
int ret;
-#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
- struct wpa_supplicant *iface;
-#endif
-
pin = os_strchr(cmd, ' ');
if (pin)
*pin++ = '\0';
if (os_strcmp(cmd, "any") == 0)
_bssid = NULL;
- else if (hwaddr_aton(cmd, bssid)) {
+ else if (os_strcmp(cmd, "get") == 0) {
+ ret = wps_generate_pin();
+ goto done;
+ } else if (hwaddr_aton(cmd, bssid)) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
cmd);
return -1;
}
-#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
- if (iface->ap_iface){
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: iface 0x%08x wpa_s->ap_iface %p", (u32)iface, iface->ap_iface);
- /* Call the wps registrar for the main interface */
- wpa_supplicant_ap_wps_pin(iface, _bssid, pin,
- buf, buflen);
- return 0;
- }
- else
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: ap_iface is not set iface 0x%08x", (u32)iface);
- }
-#elif defined CONFIG_AP
+#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
buf, buflen);
@@ -400,6 +464,7 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
if (ret < 0)
return -1;
+done:
/* Return the generated PIN */
ret = os_snprintf(buf, buflen, "%08d", ret);
if (ret < 0 || (size_t) ret >= buflen)
@@ -699,84 +764,110 @@ static int wpa_supplicant_ctrl_iface_ibss_rsn(
#endif /* CONFIG_IBSS_RSN */
-static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
- char *rsp)
+int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ const char *field,
+ const char *value)
{
#ifdef IEEE8021X_EAPOL
- char *pos, *id_pos;
- int id;
- struct wpa_ssid *ssid;
- struct eap_peer_config *eap;
-
- pos = os_strchr(rsp, '-');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- id_pos = pos;
- pos = os_strchr(pos, ':');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- id = atoi(id_pos);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
- wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
- (u8 *) pos, os_strlen(pos));
+ struct eap_peer_config *eap = &ssid->eap;
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
- "to update", id);
- return -1;
- }
- eap = &ssid->eap;
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
+ wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
+ (const u8 *) value, os_strlen(value));
- if (os_strcmp(rsp, "IDENTITY") == 0) {
+ switch (wpa_supplicant_ctrl_req_from_string(field)) {
+ case WPA_CTRL_REQ_EAP_IDENTITY:
os_free(eap->identity);
- eap->identity = (u8 *) os_strdup(pos);
- eap->identity_len = os_strlen(pos);
+ eap->identity = (u8 *) os_strdup(value);
+ eap->identity_len = os_strlen(value);
eap->pending_req_identity = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
- } else if (os_strcmp(rsp, "PASSWORD") == 0) {
+ break;
+ case WPA_CTRL_REQ_EAP_PASSWORD:
os_free(eap->password);
- eap->password = (u8 *) os_strdup(pos);
- eap->password_len = os_strlen(pos);
+ eap->password = (u8 *) os_strdup(value);
+ eap->password_len = os_strlen(value);
eap->pending_req_password = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
- } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
+ break;
+ case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
os_free(eap->new_password);
- eap->new_password = (u8 *) os_strdup(pos);
- eap->new_password_len = os_strlen(pos);
+ eap->new_password = (u8 *) os_strdup(value);
+ eap->new_password_len = os_strlen(value);
eap->pending_req_new_password = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
- } else if (os_strcmp(rsp, "PIN") == 0) {
+ break;
+ case WPA_CTRL_REQ_EAP_PIN:
os_free(eap->pin);
- eap->pin = os_strdup(pos);
+ eap->pin = os_strdup(value);
eap->pending_req_pin = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
- } else if (os_strcmp(rsp, "OTP") == 0) {
+ break;
+ case WPA_CTRL_REQ_EAP_OTP:
os_free(eap->otp);
- eap->otp = (u8 *) os_strdup(pos);
- eap->otp_len = os_strlen(pos);
+ eap->otp = (u8 *) os_strdup(value);
+ eap->otp_len = os_strlen(value);
os_free(eap->pending_req_otp);
eap->pending_req_otp = NULL;
eap->pending_req_otp_len = 0;
- } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
+ break;
+ case WPA_CTRL_REQ_EAP_PASSPHRASE:
os_free(eap->private_key_passwd);
- eap->private_key_passwd = (u8 *) os_strdup(pos);
+ eap->private_key_passwd = (u8 *) os_strdup(value);
eap->pending_req_passphrase = 0;
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
- } else {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
return -1;
}
return 0;
#else /* IEEE8021X_EAPOL */
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
+ return -1;
+#endif /* IEEE8021X_EAPOL */
+}
+
+
+static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
+ char *rsp)
+{
+#ifdef IEEE8021X_EAPOL
+ char *pos, *id_pos;
+ int id;
+ struct wpa_ssid *ssid;
+
+ pos = os_strchr(rsp, '-');
+ if (pos == NULL)
+ return -1;
+ *pos++ = '\0';
+ id_pos = pos;
+ pos = os_strchr(pos, ':');
+ if (pos == NULL)
+ return -1;
+ *pos++ = '\0';
+ id = atoi(id_pos);
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
+ wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
+ (u8 *) pos, os_strlen(pos));
+
+ ssid = wpa_config_get_network(wpa_s->conf, id);
+ if (ssid == NULL) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
+ "to update", id);
+ return -1;
+ }
+
+ return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp,
+ pos);
+#else /* IEEE8021X_EAPOL */
wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
return -1;
#endif /* IEEE8021X_EAPOL */
@@ -788,22 +879,10 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
char *buf, size_t buflen)
{
char *pos, *end, tmp[30];
- int res, verbose, ret;
-
-#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_P2P)
- /* We have to send status command to p2p interface if p2p_interface is started
- * otherwise we can send it to primary interface
- */
- struct wpa_supplicant* ifs;
- for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
- if ( (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO ) ||(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT )) {
- wpa_s = ifs;
- break;
- }
- }
-#endif /* defined ANDROID_BRCM_P2P_PATCH && defined CONFIG_P2P */
+ int res, verbose, wps, ret;
verbose = os_strcmp(params, "-VERBOSE") == 0;
+ wps = os_strcmp(params, "-WPS") == 0;
pos = buf;
end = buf + buflen;
if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
@@ -832,6 +911,17 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
return pos - buf;
pos += ret;
+ if (wps && ssid->passphrase &&
+ wpa_key_mgmt_wpa_psk(ssid->key_mgmt) &&
+ (ssid->mode == WPAS_MODE_AP ||
+ ssid->mode == WPAS_MODE_P2P_GO)) {
+ ret = os_snprintf(pos, end - pos,
+ "passphrase=%s\n",
+ ssid->passphrase);
+ if (ret < 0 || ret >= end - pos)
+ return pos - buf;
+ pos += ret;
+ }
if (ssid->id_str) {
ret = os_snprintf(pos, end - pos,
"id_str=%s\n",
@@ -977,50 +1067,9 @@ static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
}
-extern int wpa_debug_level;
-extern int wpa_debug_timestamp;
-
-static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf, size_t buflen)
-{
- char *pos, *end, *stamp;
- int ret;
-
- if (cmd == NULL)
- return -1;
- /* cmd: "LOG_LEVEL [<level>]" */
- if (*cmd == '\0') {
- pos = buf;
- end = buf + buflen;
- ret = os_snprintf(pos, end-pos, "Current level: %d\n"
- "{0-EXCESSIVE, 1-MSGDUMP, 2-DEBUG, 3-INFO, 4-WARNING, 5-ERROR}\n"
- "Timestamp: %d\n", wpa_debug_level, wpa_debug_timestamp);
- if ((ret < 0) || (ret >= end - pos))
- ret = 0;
- return ret;
- }
-
- cmd++;
- stamp = os_strchr(cmd, ' ');
- if (stamp) {
- *stamp++ = '\0';
- while (*stamp == ' ')
- stamp++;
- }
-
- if (cmd && os_strlen(cmd))
- wpa_debug_level = atoi(cmd);
-
- if (stamp && os_strlen(stamp))
- wpa_debug_timestamp = atoi(stamp);
-
- os_memcpy(buf, "OK\n", 3);
- return 3;
-}
-
-
static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf, size_t buflen)
+ char *cmd, char *buf,
+ size_t buflen)
{
u8 bssid[ETH_ALEN];
struct wpa_blacklist *e;
@@ -1033,8 +1082,9 @@ static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
end = buf + buflen;
e = wpa_s->blacklist;
while (e) {
- ret = os_snprintf(pos, end-pos, MACSTR"\n", MAC2STR(e->bssid));
- if ((ret < 0) || (ret >= end - pos))
+ ret = os_snprintf(pos, end - pos, MACSTR "\n",
+ MAC2STR(e->bssid));
+ if (ret < 0 || ret >= end - pos)
return pos - buf;
pos += ret;
e = e->next;
@@ -1051,23 +1101,118 @@ static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd);
if (hwaddr_aton(cmd, bssid)) {
- wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", cmd);
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd);
return -1;
}
- /* Add the BSSID twice, so its count will be 2, causing it to be
- skipped when processing scan results. */
+ /*
+ * Add the BSSID twice, so its count will be 2, causing it to be
+ * skipped when processing scan results.
+ */
ret = wpa_blacklist_add(wpa_s, bssid);
- if (ret < 0)
+ if (ret != 0)
return -1;
ret = wpa_blacklist_add(wpa_s, bssid);
- if (ret < 0)
+ if (ret != 0)
return -1;
os_memcpy(buf, "OK\n", 3);
return 3;
}
+extern int wpa_debug_level;
+extern int wpa_debug_timestamp;
+
+static const char * debug_level_str(int level)
+{
+ switch (level) {
+ case MSG_EXCESSIVE:
+ return "EXCESSIVE";
+ case MSG_MSGDUMP:
+ return "MSGDUMP";
+ case MSG_DEBUG:
+ return "DEBUG";
+ case MSG_INFO:
+ return "INFO";
+ case MSG_WARNING:
+ return "WARNING";
+ case MSG_ERROR:
+ return "ERROR";
+ default:
+ return "?";
+ }
+}
+
+
+static int str_to_debug_level(const char *s)
+{
+ if (os_strcasecmp(s, "EXCESSIVE") == 0)
+ return MSG_EXCESSIVE;
+ if (os_strcasecmp(s, "MSGDUMP") == 0)
+ return MSG_MSGDUMP;
+ if (os_strcasecmp(s, "DEBUG") == 0)
+ return MSG_DEBUG;
+ if (os_strcasecmp(s, "INFO") == 0)
+ return MSG_INFO;
+ if (os_strcasecmp(s, "WARNING") == 0)
+ return MSG_WARNING;
+ if (os_strcasecmp(s, "ERROR") == 0)
+ return MSG_ERROR;
+ return -1;
+}
+
+
+static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
+ char *cmd, char *buf,
+ size_t buflen)
+{
+ char *pos, *end, *stamp;
+ int ret;
+
+ if (cmd == NULL) {
+ return -1;
+ }
+
+ /* cmd: "LOG_LEVEL [<level>]" */
+ if (*cmd == '\0') {
+ pos = buf;
+ end = buf + buflen;
+ ret = os_snprintf(pos, end - pos, "Current level: %s\n"
+ "Timestamp: %d\n",
+ debug_level_str(wpa_debug_level),
+ wpa_debug_timestamp);
+ if (ret < 0 || ret >= end - pos)
+ ret = 0;
+
+ return ret;
+ }
+
+ while (*cmd == ' ')
+ cmd++;
+
+ stamp = os_strchr(cmd, ' ');
+ if (stamp) {
+ *stamp++ = '\0';
+ while (*stamp == ' ') {
+ stamp++;
+ }
+ }
+
+ if (cmd && os_strlen(cmd)) {
+ int level = str_to_debug_level(cmd);
+ if (level < 0)
+ return -1;
+ wpa_debug_level = level;
+ }
+
+ if (stamp && os_strlen(stamp))
+ wpa_debug_timestamp = atoi(stamp);
+
+ os_memcpy(buf, "OK\n", 3);
+ return 3;
+}
+
+
static int wpa_supplicant_ctrl_iface_list_networks(
struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
{
@@ -1544,8 +1689,8 @@ static int wpa_supplicant_ctrl_iface_remove_network(
wpas_notify_network_removed(wpa_s, remove_ssid);
wpa_config_remove_network(wpa_s->conf, id);
}
+ eapol_sm_invalidate_cached_session(wpa_s->eapol);
if (wpa_s->current_ssid) {
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
wpa_sm_set_config(wpa_s->wpa, NULL);
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
wpa_supplicant_disassociate(wpa_s,
@@ -1558,6 +1703,8 @@ static int wpa_supplicant_ctrl_iface_remove_network(
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
ssid = wpa_config_get_network(wpa_s->conf, id);
+ if (ssid)
+ wpas_notify_network_removed(wpa_s, ssid);
if (ssid == NULL ||
wpa_config_remove_network(wpa_s->conf, id) < 0) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
@@ -1565,12 +1712,15 @@ static int wpa_supplicant_ctrl_iface_remove_network(
return -1;
}
- if (ssid == wpa_s->current_ssid) {
+ if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
/*
- * Invalidate the EAP session cache if the current network is
- * removed.
+ * Invalidate the EAP session cache if the current or
+ * previously used network is removed.
*/
eapol_sm_invalidate_cached_session(wpa_s->eapol);
+ }
+
+ if (ssid == wpa_s->current_ssid) {
wpa_sm_set_config(wpa_s->wpa, NULL);
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
@@ -1618,10 +1768,12 @@ static int wpa_supplicant_ctrl_iface_set_network(
return -1;
}
- if (wpa_s->current_ssid == ssid) {
+ wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
+
+ if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
/*
* Invalidate the EAP session cache if anything in the current
- * configuration changes.
+ * or previously used configuration changes.
*/
eapol_sm_invalidate_cached_session(wpa_s->eapol);
}
@@ -2012,6 +2164,41 @@ static int wpa_supplicant_ctrl_iface_get_capability(
}
+#ifdef CONFIG_INTERWORKING
+static char * anqp_add_hex(char *pos, char *end, const char *title,
+ struct wpabuf *data)
+{
+ char *start = pos;
+ size_t i;
+ int ret;
+ const u8 *d;
+
+ if (data == NULL)
+ return start;
+
+ ret = os_snprintf(pos, end - pos, "%s=", title);
+ if (ret < 0 || ret >= end - pos)
+ return start;
+ pos += ret;
+
+ d = wpabuf_head_u8(data);
+ for (i = 0; i < wpabuf_len(data); i++) {
+ ret = os_snprintf(pos, end - pos, "%02x", *d++);
+ if (ret < 0 || ret >= end - pos)
+ return start;
+ pos += ret;
+ }
+
+ ret = os_snprintf(pos, end - pos, "\n");
+ if (ret < 0 || ret >= end - pos)
+ return start;
+ pos += ret;
+
+ return pos;
+}
+#endif /* CONFIG_INTERWORKING */
+
+
static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
const char *cmd, char *buf,
size_t buflen)
@@ -2085,12 +2272,6 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
return pos - buf;
pos += ret;
}
- if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
- ret = os_snprintf(pos, end - pos, "[P2P]");
- if (ret < 0 || ret >= end - pos)
- return pos - buf;
- pos += ret;
- }
ret = os_snprintf(pos, end - pos, "\n");
if (ret < 0 || ret >= end - pos)
@@ -2127,6 +2308,12 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
return pos - buf;
pos += ret;
}
+ if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
+ ret = os_snprintf(pos, end - pos, "[P2P]");
+ if (ret < 0 || ret >= end - pos)
+ return pos - buf;
+ pos += ret;
+ }
ret = os_snprintf(pos, end - pos, "\n");
if (ret < 0 || ret >= end - pos)
@@ -2155,6 +2342,20 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
pos += ret;
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ pos = anqp_add_hex(pos, end, "anqp_venue_name", bss->anqp_venue_name);
+ pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
+ bss->anqp_network_auth_type);
+ pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
+ bss->anqp_roaming_consortium);
+ pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
+ bss->anqp_ip_addr_type_availability);
+ pos = anqp_add_hex(pos, end, "anqp_nai_realm", bss->anqp_nai_realm);
+ pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp);
+ pos = anqp_add_hex(pos, end, "anqp_domain_name",
+ bss->anqp_domain_name);
+#endif /* CONFIG_INTERWORKING */
+
return pos - buf;
}
@@ -2220,6 +2421,9 @@ static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
char *addr)
{
+#ifdef CONFIG_NO_SCAN_PROCESSING
+ return -1;
+#else /* CONFIG_NO_SCAN_PROCESSING */
u8 bssid[ETH_ALEN];
struct wpa_bss *bss;
struct wpa_ssid *ssid = wpa_s->current_ssid;
@@ -2254,6 +2458,7 @@ static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
wpa_supplicant_connect(wpa_s, bss, ssid);
return 0;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
}
@@ -2329,9 +2534,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
wps_method = WPS_PIN_KEYPAD;
if (pos) {
*pos++ = '\0';
- if (os_strncmp(pos, "label", 5) == 0)
- wps_method = WPS_PIN_LABEL;
- else if (os_strncmp(pos, "display", 7) == 0)
+ if (os_strncmp(pos, "display", 7) == 0)
wps_method = WPS_PIN_DISPLAY;
}
}
@@ -2373,7 +2576,7 @@ static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
u8 addr[ETH_ALEN];
char *pos;
- /* <addr> <config method> */
+ /* <addr> <config method> [join] */
if (hwaddr_aton(cmd, addr))
return -1;
@@ -2383,7 +2586,8 @@ static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
return -1;
pos++;
- return wpas_p2p_prov_disc(wpa_s, addr, pos);
+ return wpas_p2p_prov_disc(wpa_s, addr, pos,
+ os_strstr(pos, "join") != NULL);
}
@@ -2392,16 +2596,6 @@ static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
{
struct wpa_ssid *ssid = wpa_s->current_ssid;
-#ifdef ANDROID_BRCM_P2P_PATCH
- struct wpa_supplicant *ifs = NULL;
-
- for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
- if((ifs->ap_iface) &&
- (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO)) {
- ssid = ifs->current_ssid;
- }
- }
-#endif
if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
ssid->passphrase == NULL)
return -1;
@@ -2441,8 +2635,7 @@ static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
if (*pos != ' ')
return -1;
pos++;
- ref = (unsigned long) wpas_p2p_sd_request_upnp(wpa_s, dst,
- version, pos);
+ ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos);
} else {
len = os_strlen(pos);
if (len & 1)
@@ -2456,9 +2649,11 @@ static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
return -1;
}
- ref = (unsigned long) wpas_p2p_sd_request(wpa_s, dst, tlvs);
+ ref = wpas_p2p_sd_request(wpa_s, dst, tlvs);
wpabuf_free(tlvs);
}
+ if (ref == 0)
+ return -1;
res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
if (res < 0 || (unsigned) res >= buflen)
return -1;
@@ -2474,7 +2669,7 @@ static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
if (sscanf(cmd, "%llx", &val) != 1)
return -1;
req = val;
- return wpas_p2p_sd_cancel_request(wpa_s, (void *) (unsigned long) req);
+ return wpas_p2p_sd_cancel_request(wpa_s, req);
}
@@ -2806,7 +3001,11 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen)
{
u8 addr[ETH_ALEN], *addr_ptr;
- int next;
+ int next, res;
+ const struct p2p_peer_info *info;
+ char *pos, *end;
+ char devtype[WPS_DEV_TYPE_BUFSIZE];
+ struct wpa_ssid *ssid;
if (!wpa_s->global->p2p)
return -1;
@@ -2826,28 +3025,56 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
next = 0;
}
- return p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next,
- buf, buflen);
-}
+ info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
+ if (info == NULL)
+ return -1;
-#ifdef ANDROID_BRCM_P2P_PATCH
-struct wpa_supplicant* p2p_get_apif(struct wpa_supplicant* wpa_s)
-{
- struct wpa_supplicant* iface;
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
- if (iface->ap_iface)
- return iface;
- return wpa_s;
-}
-struct wpa_supplicant* p2p_get_clientif(struct wpa_supplicant* wpa_s)
-{
- struct wpa_supplicant* iface;
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
- if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
- return iface;
- return wpa_s;
+ pos = buf;
+ end = buf + buflen;
+
+ res = os_snprintf(pos, end - pos, MACSTR "\n"
+ "pri_dev_type=%s\n"
+ "device_name=%s\n"
+ "manufacturer=%s\n"
+ "model_name=%s\n"
+ "model_number=%s\n"
+ "serial_number=%s\n"
+ "config_methods=0x%x\n"
+ "dev_capab=0x%x\n"
+ "group_capab=0x%x\n"
+ "level=%d\n",
+ MAC2STR(info->p2p_device_addr),
+ wps_dev_type_bin2str(info->pri_dev_type,
+ devtype, sizeof(devtype)),
+ info->device_name,
+ info->manufacturer,
+ info->model_name,
+ info->model_number,
+ info->serial_number,
+ info->config_methods,
+ info->dev_capab,
+ info->group_capab,
+ info->level);
+ if (res < 0 || res >= end - pos)
+ return pos - buf;
+ pos += res;
+
+ ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr);
+ if (ssid) {
+ res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id);
+ if (res < 0 || res >= end - pos)
+ return pos - buf;
+ pos += res;
+ }
+
+ res = p2p_get_peer_info_txt(info, pos, end - pos);
+ if (res < 0)
+ return pos - buf;
+ pos += res;
+
+ return pos - buf;
}
-#endif
+
static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
{
@@ -2903,46 +3130,17 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
return -1;
wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
"start=%d duration=%d", count, start, duration);
-#ifdef ANDROID_BRCM_P2P_PATCH
- return wpas_p2p_set_noa(p2p_get_apif(wpa_s), count, start, duration);
-#else
return wpas_p2p_set_noa(wpa_s, count, start, duration);
-#endif
}
if (os_strcmp(cmd, "ps") == 0)
-#ifdef ANDROID_BRCM_P2P_PATCH
- return wpas_drv_set_p2p_powersave(p2p_get_clientif(wpa_s), atoi(param), -1, -1);
-#else
return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
-#endif
if (os_strcmp(cmd, "oppps") == 0)
-#ifdef ANDROID_BRCM_P2P_PATCH
- return wpas_drv_set_p2p_powersave(p2p_get_apif(wpa_s), -1, atoi(param), -1);
-#else
return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
-#endif
if (os_strcmp(cmd, "ctwindow") == 0)
-#ifdef ANDROID_BRCM_P2P_PATCH
- return wpa_drv_set_p2p_powersave(p2p_get_apif(wpa_s), -1, -1, atoi(param));
-#else
return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
-#endif
-
- if (os_strcmp(cmd, "disabled") == 0) {
- wpa_s->global->p2p_disabled = atoi(param);
- wpa_printf(MSG_DEBUG, "P2P functionality %s",
- wpa_s->global->p2p_disabled ?
- "disabled" : "enabled");
- if (wpa_s->global->p2p_disabled) {
- wpas_p2p_stop_find(wpa_s);
- os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
- p2p_flush(wpa_s->global->p2p);
- }
- return 0;
- }
if (os_strcmp(cmd, "disabled") == 0) {
wpa_s->global->p2p_disabled = atoi(param);
@@ -3081,6 +3279,59 @@ static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst)
+{
+ u8 bssid[ETH_ALEN];
+ struct wpa_bss *bss;
+
+ if (hwaddr_aton(dst, bssid)) {
+ wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst);
+ return -1;
+ }
+
+ bss = wpa_bss_get_bssid(wpa_s, bssid);
+ if (bss == NULL) {
+ wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR,
+ MAC2STR(bssid));
+ return -1;
+ }
+
+ return interworking_connect(wpa_s, bss);
+}
+
+
+static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
+{
+ u8 dst_addr[ETH_ALEN];
+ int used;
+ char *pos;
+#define MAX_ANQP_INFO_ID 100
+ u16 id[MAX_ANQP_INFO_ID];
+ size_t num_id = 0;
+
+ used = hwaddr_aton2(dst, dst_addr);
+ if (used < 0)
+ return -1;
+ pos = dst + used;
+ while (num_id < MAX_ANQP_INFO_ID) {
+ id[num_id] = atoi(pos);
+ if (id[num_id])
+ num_id++;
+ pos = os_strchr(pos + 1, ',');
+ if (pos == NULL)
+ break;
+ pos++;
+ }
+
+ if (num_id == 0)
+ return -1;
+
+ return anqp_send_req(wpa_s, dst_addr, id, num_id);
+}
+#endif /* CONFIG_INTERWORKING */
+
+
static int wpa_supplicant_ctrl_iface_sta_autoconnect(
struct wpa_supplicant *wpa_s, char *cmd)
{
@@ -3108,7 +3359,7 @@ static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
return ret;
}
-
+#ifdef ANDROID
static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen)
{
@@ -3119,7 +3370,7 @@ static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
ret = sprintf(buf, "%s\n", "OK");
return ret;
}
-
+#endif
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
char *buf, size_t *resp_len)
@@ -3186,6 +3437,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strcmp(buf, "LOGOFF") == 0) {
eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
} else if (os_strcmp(buf, "REASSOCIATE") == 0) {
+ wpa_s->normal_scans = 0;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
reply_len = -1;
else {
@@ -3194,6 +3446,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
wpa_supplicant_req_scan(wpa_s, 0, 0);
}
} else if (os_strcmp(buf, "RECONNECT") == 0) {
+ wpa_s->normal_scans = 0;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
reply_len = -1;
else if (wpa_s->disconnected) {
@@ -3375,18 +3628,6 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpas_p2p_cancel(wpa_s))
reply_len = -1;
} else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
- #if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_P2P)
- /* We have to send presence command to p2p interface if p2p_interface is started
- * otherwise we can send it to primary interface
- */
- struct wpa_supplicant* ifs;
- for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
- if ( (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO ) ||(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT )) {
- wpa_s = ifs;
- break;
- }
- }
- #endif /* defined ANDROID_BRCM_P2P_PATCH && defined CONFIG_P2P */
if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
reply_len = -1;
} else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
@@ -3399,6 +3640,23 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
reply_len = -1;
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ } else if (os_strcmp(buf, "FETCH_ANQP") == 0) {
+ if (interworking_fetch_anqp(wpa_s) < 0)
+ reply_len = -1;
+ } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
+ interworking_stop_fetch_anqp(wpa_s);
+ } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) {
+ if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") !=
+ NULL) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) {
+ if (ctrl_interworking_connect(wpa_s, buf + 21) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) {
+ if (get_anqp(wpa_s, buf + 9) < 0)
+ reply_len = -1;
+#endif /* CONFIG_INTERWORKING */
} else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
{
if (wpa_supplicant_ctrl_iface_ctrl_rsp(
@@ -3414,21 +3672,23 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "BSSID ", 6) == 0) {
if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
reply_len = -1;
- } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_log_level(wpa_s, buf + 9,
- reply, reply_size);
} else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_blacklist(wpa_s, buf + 9,
- reply, reply_size);
+ reply_len = wpa_supplicant_ctrl_iface_blacklist(
+ wpa_s, buf + 9, reply, reply_size);
+ } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
+ reply_len = wpa_supplicant_ctrl_iface_log_level(
+ wpa_s, buf + 9, reply, reply_size);
} else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
reply_len = wpa_supplicant_ctrl_iface_list_networks(
wpa_s, reply, reply_size);
} else if (os_strcmp(buf, "DISCONNECT") == 0) {
wpa_s->reassociate = 0;
wpa_s->disconnected = 1;
+ wpa_supplicant_cancel_sched_scan(wpa_s);
wpa_supplicant_deauthenticate(wpa_s,
WLAN_REASON_DEAUTH_LEAVING);
} else if (os_strcmp(buf, "SCAN") == 0) {
+ wpa_s->normal_scans = 0;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
reply_len = -1;
else {
@@ -3534,9 +3794,13 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
reply_size);
+#ifdef ANDROID
} else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
reply_size);
+#endif
+ } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
+ eapol_sm_request_reauth(wpa_s->eapol);
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
@@ -3733,8 +3997,11 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
char *reply;
const int reply_size = 2048;
int reply_len;
+ int level = MSG_DEBUG;
- wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
+ if (os_strcmp(buf, "PING") == 0)
+ level = MSG_EXCESSIVE;
+ wpa_hexdump_ascii(level, "RX global ctrl_iface",
(const u8 *) buf, os_strlen(buf));
reply = os_malloc(reply_size);
diff --git a/wpa_supplicant/ctrl_iface.h b/wpa_supplicant/ctrl_iface.h
index 051d99a..88ae6b7 100644
--- a/wpa_supplicant/ctrl_iface.h
+++ b/wpa_supplicant/ctrl_iface.h
@@ -95,6 +95,21 @@ void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv);
void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv);
/**
+ * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @ssid: Pointer to the network block the reply is for
+ * @field: field the response is a reply for
+ * @value: value (ie, password, etc) for @field
+ * Returns: 0 on success, non-zero on error
+ *
+ * Helper function to handle replies to control interface requests.
+ */
+int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ const char *field,
+ const char *value);
+
+/**
* wpa_supplicant_global_ctrl_iface_init - Initialize global control interface
* @global: Pointer to global data from wpa_supplicant_init()
* Returns: Pointer to private data on success, %NULL on failure
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 9ad75d4..306a222 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -281,7 +281,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
goto fail;
#ifdef ANDROID
os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
- wpa_s->ifname);
+ wpa_s->conf->ctrl_interface);
priv->sock = android_get_control_socket(addr.sun_path);
if (priv->sock >= 0)
goto havesock;
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c
index 788f736..5f9e64a 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.c
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.c
@@ -705,18 +705,26 @@ dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
* @param iter A valid DBusMessageIter pointing to the start of the dict
* @param iter_dict (out) A DBusMessageIter to be passed to
* wpa_dbus_dict_read_next_entry()
+ * @error on failure a descriptive error
* @return TRUE on success, FALSE on failure
*
*/
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
- DBusMessageIter *iter_dict)
+ DBusMessageIter *iter_dict,
+ DBusError *error)
{
- if (!iter || !iter_dict)
+ if (!iter || !iter_dict) {
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "[internal] missing message iterators");
return FALSE;
+ }
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY)
+ dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) {
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "unexpected message argument types");
return FALSE;
+ }
dbus_message_iter_recurse(iter, iter_dict);
return TRUE;
@@ -1087,13 +1095,13 @@ void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
os_free(entry->strarray_value[i]);
os_free(entry->strarray_value);
break;
+ case WPAS_DBUS_TYPE_BINARRAY:
+ for (i = 0; i < entry->array_len; i++)
+ wpabuf_free(entry->binarray_value[i]);
+ os_free(entry->binarray_value);
+ break;
}
break;
- case WPAS_DBUS_TYPE_BINARRAY:
- for (i = 0; i < entry->array_len; i++)
- wpabuf_free(entry->binarray_value[i]);
- os_free(entry->binarray_value);
- break;
}
memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.h b/wpa_supplicant/dbus/dbus_dict_helpers.h
index 9e90c50..2f6eb45 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.h
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.h
@@ -156,7 +156,8 @@ struct wpa_dbus_dict_entry {
};
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
- DBusMessageIter *iter_dict);
+ DBusMessageIter *iter_dict,
+ DBusError *error);
dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
struct wpa_dbus_dict_entry *entry);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 533cb32..2bf9be8 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -22,11 +22,11 @@
#include "../config.h"
#include "../wpa_supplicant_i.h"
#include "../bss.h"
+#include "../wpas_glue.h"
#include "dbus_new_helpers.h"
#include "dbus_dict_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
-#include "dbus_common.h"
#include "dbus_common_i.h"
#include "dbus_new_handlers_p2p.h"
#include "p2p/p2p.h"
@@ -45,7 +45,7 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
{
struct wpas_dbus_priv *iface;
DBusMessage *msg;
- DBusMessageIter iter, iter_dict;
+ DBusMessageIter iter;
iface = wpa_s->global->dbus;
@@ -64,14 +64,9 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
goto err;
if (properties) {
- if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
- goto err;
-
- wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- &iter_dict);
-
- if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ if (!wpa_dbus_get_object_properties(
+ iface, wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE, &iter))
goto err;
}
@@ -160,7 +155,7 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
{
struct wpas_dbus_priv *iface;
DBusMessage *msg;
- DBusMessageIter iter, iter_dict;
+ DBusMessageIter iter;
iface = wpa_s->global->dbus;
@@ -180,14 +175,9 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
goto err;
if (properties) {
- if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
- goto err;
-
- wpa_dbus_get_object_properties(iface, bss_obj_path,
- WPAS_DBUS_NEW_IFACE_BSS,
- &iter_dict);
-
- if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ if (!wpa_dbus_get_object_properties(iface, bss_obj_path,
+ WPAS_DBUS_NEW_IFACE_BSS,
+ &iter))
goto err;
}
@@ -307,7 +297,7 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
{
struct wpas_dbus_priv *iface;
DBusMessage *msg;
- DBusMessageIter iter, iter_dict;
+ DBusMessageIter iter;
char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
iface = wpa_s->global->dbus;
@@ -333,14 +323,9 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
goto err;
if (properties) {
- if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
- goto err;
-
- wpa_dbus_get_object_properties(iface, net_obj_path,
- WPAS_DBUS_NEW_IFACE_NETWORK,
- &iter_dict);
-
- if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ if (!wpa_dbus_get_object_properties(
+ iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
+ &iter))
goto err;
}
@@ -397,6 +382,67 @@ void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
/**
+ * wpas_dbus_signal_network_request - Indicate that additional information
+ * (EAP password, etc.) is required to complete the association to this SSID
+ * @wpa_s: %wpa_supplicant network interface data
+ * @rtype: The specific additional information required
+ * @default_text: Optional description of required information
+ *
+ * Request additional information or passwords to complete an association
+ * request.
+ */
+void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype,
+ const char *default_txt)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+ DBusMessageIter iter;
+ char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
+ const char *field, *txt = NULL, *net_ptr;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (iface == NULL)
+ return;
+
+ field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
+ if (field == NULL)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "NetworkRequest");
+ if (msg == NULL)
+ return;
+
+ os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
+ wpa_s->dbus_new_path, ssid->id);
+ net_ptr = &net_obj_path[0];
+
+ dbus_message_iter_init_append(msg, &iter);
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &net_ptr))
+ goto err;
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field))
+ goto err;
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
+ goto err;
+
+ dbus_connection_send(iface->con, msg, NULL);
+ dbus_message_unref(msg);
+ return;
+
+err:
+ wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+ dbus_message_unref(msg);
+}
+
+
+/**
* wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
* @wpa_s: %wpa_supplicant network interface data
* @ssid: configured network which Enabled property has changed
@@ -821,7 +867,7 @@ void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
return;
/* Check if this is a known peer */
- if (p2p_get_peer_info(wpa_s->global->p2p, dev_addr, 0, NULL, 0) < 0)
+ if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
goto error;
os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
@@ -920,7 +966,7 @@ static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
/**
* wpas_dbus_signal_p2p_group_started - Signals P2P group has
- * started.Emitted when a group is succesfully started
+ * started. Emitted when a group is successfully started
* irrespective of the role (client/GO) of the current device
*
* @wpa_s: %wpa_supplicant network interface data
@@ -998,35 +1044,118 @@ nomem:
* on status.
* @status: Status of the GO neg request. 0 for success, other for errors.
*/
-void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status)
+void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
+ struct p2p_go_neg_results *res)
{
DBusMessage *msg;
- DBusMessageIter iter;
+ DBusMessageIter iter, dict_iter;
+ DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
struct wpas_dbus_priv *iface;
+ char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
+ dbus_int32_t freqs[P2P_MAX_CHANNELS];
+ dbus_int32_t *f_array = freqs;
+
iface = wpa_s->global->dbus;
+ os_memset(freqs, 0, sizeof(freqs));
/* Do nothing if the control interface is not turned on */
if (iface == NULL)
return;
+ os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
+ wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
+ path = peer_obj_path;
+
msg = dbus_message_new_signal(wpa_s->dbus_new_path,
WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- status ? "GONegotiationFailure" :
- "GONegotiationSuccess");
+ res->status ? "GONegotiationFailure" :
+ "GONegotiationSuccess");
if (msg == NULL)
return;
- if (status) {
- dbus_message_iter_init_append(msg, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32,
- &status)) {
- wpa_printf(MSG_ERROR,
- "dbus: Failed to construct signal");
+ dbus_message_iter_init_append(msg, &iter);
+ if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
+ goto err;
+ if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
+ path) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
+ goto err;
+
+ if (!res->status) {
+ int i = 0;
+ int freq_list_num = 0;
+
+ if (res->role_go) {
+ if (!wpa_dbus_dict_append_byte_array(
+ &dict_iter, "passphrase",
+ (const char *) res->passphrase,
+ sizeof(res->passphrase)))
+ goto err;
+ }
+
+ if (!wpa_dbus_dict_append_string(&dict_iter, "role_go",
+ res->role_go ? "GO" :
+ "client") ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
+ res->freq) ||
+ !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
+ (const char *) res->ssid,
+ res->ssid_len) ||
+ !wpa_dbus_dict_append_byte_array(&dict_iter,
+ "peer_device_addr",
+ (const char *)
+ res->peer_device_addr,
+ ETH_ALEN) ||
+ !wpa_dbus_dict_append_byte_array(&dict_iter,
+ "peer_interface_addr",
+ (const char *)
+ res->peer_interface_addr,
+ ETH_ALEN) ||
+ !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
+ p2p_wps_method_text(
+ res->wps_method)))
goto err;
+
+ for (i = 0; i < P2P_MAX_CHANNELS; i++) {
+ if (res->freq_list[i]) {
+ freqs[i] = res->freq_list[i];
+ freq_list_num++;
+ }
}
+
+ if (!wpa_dbus_dict_begin_array(&dict_iter,
+ "frequency_list",
+ DBUS_TYPE_INT32_AS_STRING,
+ &iter_dict_entry,
+ &iter_dict_val,
+ &iter_dict_array))
+ goto err;
+
+ if (!dbus_message_iter_append_fixed_array(&iter_dict_array,
+ DBUS_TYPE_INT32,
+ &f_array,
+ freq_list_num))
+ goto err;
+
+ if (!wpa_dbus_dict_end_array(&dict_iter,
+ &iter_dict_entry,
+ &iter_dict_val,
+ &iter_dict_array))
+ goto err;
+
+ if (!wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
+ res->persistent_group) ||
+ !wpa_dbus_dict_append_uint32(&dict_iter,
+ "peer_config_timeout",
+ res->peer_config_timeout))
+ goto err;
}
+ if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
+ goto err;
+
dbus_connection_send(iface->con, msg, NULL);
err:
dbus_message_unref(msg);
@@ -1228,7 +1357,7 @@ void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
return;
/* Check if this is a known peer */
- if (p2p_get_peer_info(wpa_s->global->p2p, sa, 0, NULL, 0) < 0)
+ if (!p2p_peer_known(wpa_s->global->p2p, sa))
goto error;
os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
@@ -1297,7 +1426,7 @@ void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
return;
/* Check if this is a known peer */
- if (p2p_get_peer_info(wpa_s->global->p2p, sa, 0, NULL, 0) < 0)
+ if (!p2p_peer_known(wpa_s->global->p2p, sa))
goto error;
os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
@@ -1345,7 +1474,7 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
{
struct wpas_dbus_priv *iface;
DBusMessage *msg;
- DBusMessageIter iter, iter_dict;
+ DBusMessageIter iter;
char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
iface = wpa_s->global->dbus;
@@ -1371,15 +1500,9 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
goto err;
if (properties) {
- if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
- goto err;
-
- wpa_dbus_get_object_properties(
- iface, pgrp_obj_path,
- WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP,
- &iter_dict);
-
- if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
+ if (!wpa_dbus_get_object_properties(
+ iface, pgrp_obj_path,
+ WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter))
goto err;
}
@@ -1483,7 +1606,6 @@ void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
enum wpas_dbus_prop property)
{
- WPADBusPropertyAccessor getter;
char *prop;
if (wpa_s->dbus_new_path == NULL)
@@ -1491,34 +1613,24 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
switch (property) {
case WPAS_DBUS_PROP_AP_SCAN:
- getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
prop = "ApScan";
break;
case WPAS_DBUS_PROP_SCANNING:
- getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
prop = "Scanning";
break;
case WPAS_DBUS_PROP_STATE:
- getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state;
prop = "State";
break;
case WPAS_DBUS_PROP_CURRENT_BSS:
- getter = (WPADBusPropertyAccessor)
- wpas_dbus_getter_current_bss;
prop = "CurrentBSS";
break;
case WPAS_DBUS_PROP_CURRENT_NETWORK:
- getter = (WPADBusPropertyAccessor)
- wpas_dbus_getter_current_network;
prop = "CurrentNetwork";
break;
case WPAS_DBUS_PROP_BSSS:
- getter = (WPADBusPropertyAccessor) wpas_dbus_getter_bsss;
prop = "BSSs";
break;
case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
- getter = (WPADBusPropertyAccessor)
- wpas_dbus_getter_current_auth_mode;
prop = "CurrentAuthMode";
break;
default:
@@ -1685,31 +1797,26 @@ static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
- (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
- RW
+ wpas_dbus_getter_debug_level,
+ wpas_dbus_setter_debug_level
},
{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
- (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
- (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
- RW
+ wpas_dbus_getter_debug_timestamp,
+ wpas_dbus_setter_debug_timestamp
},
{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
- (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
- (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
- RW
+ wpas_dbus_getter_debug_show_keys,
+ wpas_dbus_setter_debug_show_keys
},
{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
- (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
- NULL,
- R
+ wpas_dbus_getter_interfaces,
+ NULL
},
{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
- (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
- NULL,
- R
+ wpas_dbus_getter_eap_methods,
+ NULL
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
@@ -1726,6 +1833,15 @@ static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
END_ARGS
}
},
+ { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ { "path", "o", ARG_OUT },
+ { "field", "s", ARG_OUT },
+ { "text", "s", ARG_OUT },
+ END_ARGS
+ }
+ },
+ /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
{
{ "properties", "a{sv}", ARG_OUT },
@@ -1802,20 +1918,19 @@ static void wpa_dbus_free(void *ptr)
static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
- (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
- RW
+ wpas_dbus_getter_network_properties,
+ wpas_dbus_setter_network_properties
},
{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
- (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
- (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
- RW
+ wpas_dbus_getter_enabled,
+ wpas_dbus_setter_enabled
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
+ /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
{
{ "properties", "a{sv}", ARG_OUT },
@@ -1925,8 +2040,7 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
#endif /* CONFIG_P2P */
/* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL ||
- wpa_s->dbus_new_path == NULL)
+ if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
return 0;
ctrl_iface = wpa_s->global->dbus;
if (ctrl_iface == NULL)
@@ -1949,60 +2063,51 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
- NULL,
- R
+ wpas_dbus_getter_bss_ssid,
+ NULL
},
{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
- NULL,
- R
+ wpas_dbus_getter_bss_bssid,
+ NULL
},
{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
- NULL,
- R
+ wpas_dbus_getter_bss_privacy,
+ NULL
},
{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
- NULL,
- R
+ wpas_dbus_getter_bss_mode,
+ NULL
},
{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
- NULL,
- R
+ wpas_dbus_getter_bss_signal,
+ NULL
},
{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
- NULL,
- R
+ wpas_dbus_getter_bss_frequency,
+ NULL
},
{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates,
- NULL,
- R
+ wpas_dbus_getter_bss_rates,
+ NULL
},
{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa,
- NULL,
- R
+ wpas_dbus_getter_bss_wpa,
+ NULL
},
{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn,
- NULL,
- R
+ wpas_dbus_getter_bss_rsn,
+ NULL
},
{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies,
- NULL,
- R
+ wpas_dbus_getter_bss_ies,
+ NULL
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
+ /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
{
{ "properties", "a{sv}", ARG_OUT },
@@ -2165,6 +2270,15 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
END_ARGS
}
},
+ { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) &wpas_dbus_handler_network_reply,
+ {
+ { "path", "o", ARG_IN },
+ { "field", "s", ARG_IN },
+ { "value", "s", ARG_IN },
+ END_ARGS
+ }
+ },
{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
{
@@ -2245,7 +2359,7 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
(WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
{
{ "args", "a{sv}", ARG_IN },
- { "generated_pin", "i", ARG_OUT },
+ { "generated_pin", "s", ARG_OUT },
END_ARGS
}
},
@@ -2378,108 +2492,102 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
- NULL, R
+ wpas_dbus_getter_capabilities,
+ NULL
},
{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_state,
- NULL, R
+ wpas_dbus_getter_state,
+ NULL
},
{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
- (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
- NULL, R
+ wpas_dbus_getter_scanning,
+ NULL
},
{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
- (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
- RW
+ wpas_dbus_getter_ap_scan,
+ wpas_dbus_setter_ap_scan
},
{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_age,
- (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_age,
- RW
+ wpas_dbus_getter_bss_expire_age,
+ wpas_dbus_setter_bss_expire_age
},
{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_count,
- (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_count,
- RW
+ wpas_dbus_getter_bss_expire_count,
+ wpas_dbus_setter_bss_expire_count
},
{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_country,
- (WPADBusPropertyAccessor) wpas_dbus_setter_country,
- RW
+ wpas_dbus_getter_country,
+ wpas_dbus_setter_country
},
{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
- NULL, R
+ wpas_dbus_getter_ifname,
+ NULL
},
{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
- NULL, R
+ wpas_dbus_getter_driver,
+ NULL
},
{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
- NULL, R
+ wpas_dbus_getter_bridge_ifname,
+ NULL
},
{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
- (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
- NULL, R
+ wpas_dbus_getter_current_bss,
+ NULL
},
{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
- (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
- NULL, R
+ wpas_dbus_getter_current_network,
+ NULL
},
{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_current_auth_mode,
- NULL, R
+ wpas_dbus_getter_current_auth_mode,
+ NULL
},
{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
- NULL, R
+ wpas_dbus_getter_blobs,
+ NULL
},
{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
- (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
- NULL, R
+ wpas_dbus_getter_bsss,
+ NULL
},
{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
- (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
- NULL, R
+ wpas_dbus_getter_networks,
+ NULL
},
#ifdef CONFIG_WPS
{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
- (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
- (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
- RW
+ wpas_dbus_getter_process_credentials,
+ wpas_dbus_setter_process_credentials
},
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P
{ "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_device_properties,
- (WPADBusPropertyAccessor) wpas_dbus_setter_p2p_device_properties,
- RW
+ wpas_dbus_getter_p2p_device_properties,
+ wpas_dbus_setter_p2p_device_properties
},
{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peers,
- NULL, R
+ wpas_dbus_getter_p2p_peers,
+ NULL
},
{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_role,
- NULL, R
+ wpas_dbus_getter_p2p_role,
+ NULL
},
{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group,
- NULL, R
+ wpas_dbus_getter_p2p_group,
+ NULL
},
{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo,
- NULL, R
+ wpas_dbus_getter_p2p_peergo,
+ NULL
},
{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
- (WPADBusPropertyAccessor) wpas_dbus_getter_persistent_groups,
- NULL, R
+ wpas_dbus_getter_persistent_groups,
+ NULL
},
#endif /* CONFIG_P2P */
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
@@ -2533,6 +2641,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
END_ARGS
}
},
+ /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
{
{ "properties", "a{sv}", ARG_OUT },
@@ -2553,6 +2662,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
END_ARGS
}
},
+ /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
{
{ "properties", "a{sv}", ARG_OUT },
@@ -2784,14 +2894,14 @@ int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_P2P_PEER, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_properties,
- NULL, R
+ wpas_dbus_getter_p2p_peer_properties,
+ NULL
},
{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_ies,
- NULL, R
+ wpas_dbus_getter_p2p_peer_ies,
+ NULL
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
@@ -2981,16 +3091,15 @@ int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_members,
- NULL, R
+ wpas_dbus_getter_p2p_group_members,
+ NULL
},
{ "Properties",
WPAS_DBUS_NEW_IFACE_P2P_GROUP, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties,
- (WPADBusPropertyAccessor) wpas_dbus_setter_p2p_group_properties,
- RW
+ wpas_dbus_getter_p2p_group_properties,
+ wpas_dbus_setter_p2p_group_properties
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
@@ -3111,10 +3220,10 @@ void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
static const struct wpa_dbus_property_desc
wpas_dbus_p2p_groupmember_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUPMEMBER, "a{sv}",
- (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties,
- NULL, R
+ wpas_dbus_getter_p2p_group_properties,
+ NULL
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
/**
@@ -3218,13 +3327,10 @@ void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
static const struct wpa_dbus_property_desc
wpas_dbus_persistent_group_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
- (WPADBusPropertyAccessor)
wpas_dbus_getter_persistent_group_properties,
- (WPADBusPropertyAccessor)
- wpas_dbus_setter_persistent_group_properties,
- RW
+ wpas_dbus_setter_persistent_group_properties
},
- { NULL, NULL, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, NULL, NULL }
};
/* No signals intended for persistent group objects */
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 080000c..93ce722 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -16,6 +16,7 @@
#ifndef CTRL_IFACE_DBUS_NEW_H
#define CTRL_IFACE_DBUS_NEW_H
+#include "common/defs.h"
#include "p2p/p2p.h"
struct wpa_global;
@@ -24,7 +25,6 @@ struct wpa_ssid;
struct wps_event_m2d;
struct wps_event_fail;
struct wps_credential;
-enum wpa_states;
enum wpas_dbus_prop {
WPAS_DBUS_PROP_AP_SCAN,
@@ -131,6 +131,10 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id);
+void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype,
+ const char *default_text);
void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success);
void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
const struct wps_credential *cred);
@@ -175,7 +179,8 @@ void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
int client, int network_id);
void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
-void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status);
+void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
+ struct p2p_go_neg_results *res);
void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
const struct wpa_ssid *ssid);
int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
@@ -241,6 +246,12 @@ static inline void wpas_dbus_signal_network_selected(
{
}
+static inline void wpas_dbus_signal_network_request(
+ struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+}
+
static inline void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
int success)
{
@@ -375,7 +386,8 @@ static inline int wpas_dbus_unregister_persistent_group(
}
static inline void
-wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status)
+wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
+ struct p2p_go_neg_results *res)
{
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index ee8757a..e3526d4 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -25,9 +25,9 @@
#include "../wpa_supplicant_i.h"
#include "../driver_i.h"
#include "../notify.h"
-#include "../wpas_glue.h"
#include "../bss.h"
#include "../scan.h"
+#include "../ctrl_iface.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
@@ -163,36 +163,35 @@ static struct wpa_supplicant * get_iface_by_dbus_path(
/**
* set_network_properties - Set properties of 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
* @iter: DBus message iterator containing dictionary of network
* properties to set.
- * Returns: NULL when succeed or DBus error on failure
+ * @error: On failure, an error describing the failure
+ * Returns: TRUE if the request succeeds, FALSE if it failed
*
* Sets network configuration with parameters given id DBus dictionary
*/
-DBusMessage * set_network_properties(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- DBusMessageIter *iter)
+dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ DBusMessageIter *iter,
+ DBusError *error)
{
-
struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
- DBusMessage *reply = NULL;
DBusMessageIter iter_dict;
+ char *value = NULL;
- if (!wpa_dbus_dict_open_read(iter, &iter_dict))
- return wpas_dbus_error_invalid_args(message, NULL);
+ if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
+ return FALSE;
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_error_invalid_args(message, NULL);
- break;
- }
+
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto error;
+
+ value = NULL;
if (entry.type == DBUS_TYPE_ARRAY &&
entry.array_type == DBUS_TYPE_BYTE) {
if (entry.array_len <= 0)
@@ -261,71 +260,59 @@ DBusMessage * set_network_properties(DBusMessage *message,
os_free(value);
wpa_dbus_dict_entry_clear(&entry);
- continue;
-
- error:
- os_free(value);
- reply = wpas_dbus_error_invalid_args(message, entry.key);
- wpa_dbus_dict_entry_clear(&entry);
- break;
}
- return reply;
+ return TRUE;
+
+error:
+ os_free(value);
+ wpa_dbus_dict_entry_clear(&entry);
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
}
/**
* wpas_dbus_simple_property_getter - Get basic type property
- * @message: Pointer to incoming dbus message
+ * @iter: Message iter to use when appending arguments
* @type: DBus type of property (must be basic type)
* @val: pointer to place holding property value
- * Returns: The DBus message containing response for Properties.Get call
- * or DBus error message if error occurred.
+ * @error: On failure an error describing the failure
+ * Returns: TRUE if the request was successful, FALSE if it failed
*
* Generic getter for basic type properties. Type is required to be basic.
*/
-DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
- const int type, const void *val)
+dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
+ const int type,
+ const void *val,
+ DBusError *error)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter;
+ DBusMessageIter variant_iter;
if (!dbus_type_is_basic(type)) {
- wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
- " given type is not basic");
- return wpas_dbus_error_unknown_error(message, NULL);
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: given type is not basic", __func__);
+ return FALSE;
}
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
-
- if (reply != NULL) {
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_open_container(
- &iter, DBUS_TYPE_VARIANT,
- wpa_dbus_type_as_string(type), &variant_iter) ||
- !dbus_message_iter_append_basic(&variant_iter, type,
- val) ||
- !dbus_message_iter_close_container(&iter, &variant_iter)) {
- wpa_printf(MSG_ERROR, "dbus: "
- "wpas_dbus_simple_property_getter: out of "
- "memory to put property value into "
- "message");
- dbus_message_unref(reply);
- reply = dbus_message_new_error(message,
- DBUS_ERROR_NO_MEMORY,
- NULL);
- }
- } else {
- wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:"
- " out of memory to return property value");
- reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
- }
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+ wpa_dbus_type_as_string(type),
+ &variant_iter))
+ goto error;
- return reply;
+ if (!dbus_message_iter_append_basic(&variant_iter, type, val))
+ goto error;
+
+ if (!dbus_message_iter_close_container(iter, &variant_iter))
+ goto error;
+
+ return TRUE;
+
+error:
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: error constructing reply", __func__);
+ return FALSE;
}
@@ -334,102 +321,79 @@ DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
* @message: Pointer to incoming dbus message
* @type: DBus type of property (must be basic type)
* @val: pointer to place where value being set will be stored
- * Returns: NULL or DBus error message if error occurred.
+ * Returns: TRUE if the request was successful, FALSE if it failed
*
* Generic setter for basic type properties. Type is required to be basic.
*/
-DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message,
- const int type, void *val)
+dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
+ DBusError *error,
+ const int type, void *val)
{
- DBusMessageIter iter, variant_iter;
+ DBusMessageIter variant_iter;
if (!dbus_type_is_basic(type)) {
- wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
- " given type is not basic");
- return wpas_dbus_error_unknown_error(message, NULL);
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: given type is not basic", __func__);
+ return FALSE;
}
- if (!dbus_message_iter_init(message, &iter)) {
- wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:"
- " out of memory to return scanning state");
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
- }
-
- /* omit first and second argument and get value from third */
- dbus_message_iter_next(&iter);
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &variant_iter);
-
+ /* Look at the new value */
+ dbus_message_iter_recurse(iter, &variant_iter);
if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
- wpa_printf(MSG_DEBUG, "dbus: wpas_dbus_simple_property_setter:"
- " wrong property type");
- return wpas_dbus_error_invalid_args(message,
- "wrong property type");
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "wrong property type");
+ return FALSE;
}
dbus_message_iter_get_basic(&variant_iter, val);
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_simple_array_property_getter - Get array type property
- * @message: Pointer to incoming dbus message
+ * @iter: Pointer to incoming dbus message iterator
* @type: DBus type of property array elements (must be basic type)
* @array: pointer to array of elements to put into response message
* @array_len: length of above array
- * Returns: The DBus message containing response for Properties.Get call
- * or DBus error message if error occurred.
+ * @error: a pointer to an error to fill on failure
+ * Returns: TRUE if the request succeeded, FALSE if it failed
*
* Generic getter for array type properties. Array elements type is
* required to be basic.
*/
-DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
- const int type,
- const void *array,
- size_t array_len)
+dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
+ const int type,
+ const void *array,
+ size_t array_len,
+ DBusError *error)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter, array_iter;
+ DBusMessageIter variant_iter, array_iter;
char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
const char *sub_type_str;
size_t element_size, i;
if (!dbus_type_is_basic(type)) {
- wpa_printf(MSG_ERROR, "dbus: "
- "wpas_dbus_simple_array_property_getter: given "
- "type is not basic");
- return wpas_dbus_error_unknown_error(message, NULL);
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: given type is not basic", __func__);
+ return FALSE;
}
sub_type_str = wpa_dbus_type_as_string(type);
type_str[1] = sub_type_str[0];
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
- if (reply == NULL) {
- wpa_printf(MSG_ERROR, "dbus: "
- "wpas_dbus_simple_array_property_getter: out of "
- "memory to create return message");
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+ type_str, &variant_iter)) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: failed to construct message 1", __func__);
+ return FALSE;
}
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
- type_str, &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
+ if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
sub_type_str, &array_iter)) {
- wpa_printf(MSG_ERROR, "dbus: "
- "wpas_dbus_simple_array_property_getter: out of "
- "memory to open container");
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: failed to construct message 2", __func__);
+ return FALSE;
}
switch(type) {
@@ -457,11 +421,9 @@ DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
element_size = sizeof(char *);
break;
default:
- wpa_printf(MSG_ERROR, "dbus: "
- "wpas_dbus_simple_array_property_getter: "
- "fatal: unknown element type");
- element_size = 1;
- break;
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: unknown element type %d", __func__, type);
+ return FALSE;
}
for (i = 0; i < array_len; i++) {
@@ -469,17 +431,19 @@ DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
array + i * element_size);
}
- if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
- !dbus_message_iter_close_container(&iter, &variant_iter)) {
- wpa_printf(MSG_ERROR, "dbus: "
- "wpas_dbus_simple_array_property_getter: out of "
- "memory to close container");
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: failed to construct message 3", __func__);
+ return FALSE;
}
- return reply;
+ if (!dbus_message_iter_close_container(iter, &variant_iter)) {
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: failed to construct message 4", __func__);
+ return FALSE;
+ }
+
+ return TRUE;
}
@@ -508,7 +472,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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))
@@ -612,7 +576,7 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
wpa_s = get_iface_by_dbus_path(global, path);
if (wpa_s == NULL)
reply = wpas_dbus_error_iface_unknown(message);
- else if (wpa_supplicant_remove_iface(global, wpa_s, 0)) {
+ else if (wpa_supplicant_remove_iface(global, wpa_s)) {
reply = wpas_dbus_error_unknown_error(
message, "wpa_supplicant couldn't remove this "
"interface.");
@@ -664,79 +628,86 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
/**
* wpas_dbus_getter_debug_level - Get debug level
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: DBus message with value of debug level
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "DebugLevel" property.
*/
-DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
const char *str;
int idx = wpa_debug_level;
+
if (idx < 0)
idx = 0;
if (idx > 5)
idx = 5;
str = debug_strings[idx];
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &str);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &str, error);
}
/**
* wpas_dbus_getter_debug_timestamp - Get debug timestamp
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: DBus message with value of debug timestamp
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "DebugTimestamp" property.
*/
-DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
- &wpa_debug_timestamp);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+ &wpa_debug_timestamp, error);
}
/**
* wpas_dbus_getter_debug_show_keys - Get debug show keys
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: DBus message with value of debug show_keys
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "DebugShowKeys" property.
*/
-DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
- &wpa_debug_show_keys);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+ &wpa_debug_show_keys, error);
}
/**
* wpas_dbus_setter_debug_level - Set debug level
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: %NULL or DBus error message
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "DebugLevel" property.
*/
-DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- DBusMessage *reply;
+ struct wpa_global *global = user_data;
const char *str = NULL;
int i, val = -1;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING,
- &str);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
+ &str))
+ return FALSE;
for (i = 0; debug_strings[i]; i++)
if (os_strcmp(debug_strings[i], str) == 0) {
@@ -747,137 +718,142 @@ DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
if (val < 0 ||
wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
wpa_debug_show_keys)) {
- return wpas_dbus_error_invalid_args(
- message, "Wrong debug level value");
+ dbus_set_error_const(error, DBUS_ERROR_FAILED, "wrong debug "
+ "level value");
+ return FALSE;
}
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_setter_debug_timestamp - Set debug timestamp
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: %NULL or DBus error message
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "DebugTimestamp" property.
*/
-DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply;
+ struct wpa_global *global = user_data;
dbus_bool_t val;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
- &val);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+ &val))
+ return FALSE;
wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
wpa_debug_show_keys);
-
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_setter_debug_show_keys - Set debug show keys
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: %NULL or DBus error message
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "DebugShowKeys" property.
*/
-DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply;
+ struct wpa_global *global = user_data;
dbus_bool_t val;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
- &val);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+ &val))
+ return FALSE;
wpa_supplicant_set_debug_params(global, wpa_debug_level,
wpa_debug_timestamp,
val ? 1 : 0);
-
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_getter_interfaces - Request registered interfaces list
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object paths array containing registered interfaces
- * objects paths or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Interfaces" property. Handles requests
* by dbus clients to return list of registered interfaces objects
* paths
*/
-DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
- struct wpa_global *global)
+dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_global *global = user_data;
struct wpa_supplicant *wpa_s;
const char **paths;
unsigned int i = 0, num = 0;
+ dbus_bool_t success;
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
num++;
paths = os_zalloc(num * sizeof(char*));
if (!paths) {
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
paths[i++] = wpa_s->dbus_new_path;
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- paths, num);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_OBJECT_PATH,
+ paths, num, error);
os_free(paths);
- return reply;
+ return success;
}
/**
* wpas_dbus_getter_eap_methods - Request supported EAP methods list
- * @message: Pointer to incoming dbus message
- * @nothing: not used argument. may be NULL or anything else
- * Returns: The object paths array containing supported EAP methods
- * represented by strings or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "EapMethods" property. Handles requests
* by dbus clients to return list of strings with supported EAP methods
*/
-DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
+dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- DBusMessage *reply = NULL;
char **eap_methods;
size_t num_items = 0;
+ dbus_bool_t success;
eap_methods = eap_get_names_as_string_array(&num_items);
if (!eap_methods) {
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_STRING,
- eap_methods, num_items);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_STRING,
+ eap_methods,
+ num_items, error);
while (num_items)
os_free(eap_methods[--num_items]);
os_free(eap_methods);
- return reply;
+ return success;
}
@@ -1288,6 +1264,7 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
DBusMessageIter iter;
struct wpa_ssid *ssid = NULL;
char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
+ DBusError error;
dbus_message_iter_init(message, &iter);
@@ -1305,11 +1282,15 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
ssid->disabled = 1;
wpa_config_set_network_defaults(ssid);
- reply = set_network_properties(message, wpa_s, ssid, &iter);
- if (reply) {
+ dbus_error_init(&error);
+ if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
"control interface couldn't set network "
"properties");
+ reply = wpas_dbus_reply_new_from_error(message, &error,
+ DBUS_ERROR_INVALID_ARGS,
+ "Failed to add network");
+ dbus_error_free(&error);
goto err;
}
@@ -1493,6 +1474,70 @@ out:
/**
+ * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL on success or dbus error on failure
+ *
+ * Handler function for "NetworkReply" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+#ifdef IEEE8021X_EAPOL
+ DBusMessage *reply = NULL;
+ const char *op, *field, *value;
+ char *iface = NULL, *net_id = NULL;
+ int id;
+ struct wpa_ssid *ssid;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_OBJECT_PATH, &op,
+ DBUS_TYPE_STRING, &field,
+ DBUS_TYPE_STRING, &value,
+ DBUS_TYPE_INVALID))
+ return wpas_dbus_error_invalid_args(message, NULL);
+
+ /* Extract the network ID and ensure the network */
+ /* is actually a child of this interface */
+ iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
+ if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
+ reply = wpas_dbus_error_invalid_args(message, op);
+ goto out;
+ }
+
+ id = strtoul(net_id, NULL, 10);
+ if (errno == EINVAL) {
+ reply = wpas_dbus_error_invalid_args(message, net_id);
+ goto out;
+ }
+
+ ssid = wpa_config_get_network(wpa_s->conf, id);
+ if (ssid == NULL) {
+ reply = wpas_dbus_error_network_unknown(message);
+ goto out;
+ }
+
+ if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid,
+ field, value) < 0)
+ reply = wpas_dbus_error_invalid_args(message, field);
+ else {
+ /* Tell EAP to retry immediately */
+ eapol_sm_notify_ctrl_response(wpa_s->eapol);
+ }
+
+out:
+ os_free(iface);
+ os_free(net_id);
+ return reply;
+#else /* IEEE8021X_EAPOL */
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
+ return wpas_dbus_error_unknown_error(message, "802.1X not included");
+#endif /* IEEE8021X_EAPOL */
+}
+
+
+/**
* wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
* @message: Pointer to incoming dbus message
* @wpa_s: %wpa_supplicant data structure
@@ -1683,32 +1728,24 @@ DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
/**
* wpas_dbus_getter_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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Capabilities" property of an interface.
*/
-DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
struct wpa_driver_capa capa;
int res;
- DBusMessageIter iter, iter_dict;
- DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
+ DBusMessageIter iter_dict, iter_dict_entry, iter_dict_val, iter_array,
variant_iter;
const char *scans[] = { "active", "passive", "ssid" };
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
- if (!reply)
- goto nomem;
-
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{sv}", &variant_iter))
goto nomem;
@@ -2004,36 +2041,43 @@ DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
goto nomem;
/***** Modes end */
+ if (res >= 0) {
+ dbus_int32_t max_scan_ssid = capa.max_scan_ssids;
+
+ if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxScanSSID",
+ max_scan_ssid))
+ goto nomem;
+ }
+
if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
goto nomem;
- if (!dbus_message_iter_close_container(&iter, &variant_iter))
+ if (!dbus_message_iter_close_container(iter, &variant_iter))
goto nomem;
- return reply;
+ return TRUE;
nomem:
- if (reply)
- dbus_message_unref(reply);
-
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
/**
* wpas_dbus_getter_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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "State" property.
*/
-DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
const char *str_state;
char *state_ls, *tmp;
+ dbus_bool_t success = FALSE;
str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
@@ -2041,183 +2085,204 @@ DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
*/
state_ls = tmp = os_strdup(str_state);
if (!tmp) {
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
while (*tmp) {
*tmp = tolower(*tmp);
tmp++;
}
- reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &state_ls);
+ success = wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &state_ls, error);
os_free(state_ls);
- return reply;
+ return success;
}
/**
* wpas_dbus_new_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
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "scanning" property.
*/
-DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
- &scanning);
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+ &scanning, error);
}
/**
* wpas_dbus_getter_ap_scan - Control roaming mode
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A message containong value of ap_scan variable
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter function for "ApScan" property.
*/
-DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
- &ap_scan);
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+ &ap_scan, error);
}
/**
* wpas_dbus_setter_ap_scan - Control roaming mode
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter function for "ApScan" property.
*/
-DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
dbus_uint32_t ap_scan;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
- &ap_scan);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
+ &ap_scan))
+ return FALSE;
if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
- return wpas_dbus_error_invalid_args(
- message, "ap_scan must equal 0, 1 or 2");
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "ap_scan must be 0, 1, or 2");
+ return FALSE;
}
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A message containing value of bss_expiration_age variable
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter function for "BSSExpireAge" property.
*/
-DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
- &expire_age);
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+ &expire_age, error);
}
/**
* wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter function for "BSSExpireAge" property.
*/
-DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
dbus_uint32_t expire_age;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
- &expire_age);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
+ &expire_age))
+ return FALSE;
if (wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age)) {
- return wpas_dbus_error_invalid_args(
- message, "BSSExpireAge must be >=10");
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "BSSExpireAge must be >= 10");
+ return FALSE;
}
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A message containing value of bss_expire_count variable
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter function for "BSSExpireCount" property.
*/
-DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_age;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
- &expire_count);
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
+ &expire_count, error);
}
/**
* wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter function for "BSSExpireCount" property.
*/
-DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
dbus_uint32_t expire_count;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
- &expire_count);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
+ &expire_count))
+ return FALSE;
if (wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count)) {
- return wpas_dbus_error_invalid_args(
- message, "BSSExpireCount must be >0");
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "BSSExpireCount must be > 0");
+ return FALSE;
}
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_getter_country - Control country code
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A message containong value of country variable
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter function for "Country" property.
*/
-DBusMessage * wpas_dbus_getter_country(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
char country[3];
char *str = country;
@@ -2225,103 +2290,112 @@ DBusMessage * wpas_dbus_getter_country(DBusMessage *message,
country[1] = wpa_s->conf->country[1];
country[2] = '\0';
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &str);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &str, error);
}
/**
* wpas_dbus_setter_country - Control country code
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter function for "Country" property.
*/
-DBusMessage * wpas_dbus_setter_country(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
const char *country;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING,
- &country);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
+ &country))
+ return FALSE;
- if (!country[0] || !country[1])
- return wpas_dbus_error_invalid_args(message,
- "invalid country code");
+ if (!country[0] || !country[1]) {
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "invalid country code");
+ return FALSE;
+ }
if (wpa_s->drv_priv != NULL && wpa_drv_set_country(wpa_s, country)) {
wpa_printf(MSG_DEBUG, "Failed to set country");
- return wpas_dbus_error_invalid_args(
- message, "failed to set country code");
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "failed to set country code");
+ return FALSE;
}
wpa_s->conf->country[0] = country[0];
wpa_s->conf->country[1] = country[1];
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_getter_ifname - Get interface name
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a name of network interface
- * associated with with wpa_s
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Ifname" property.
*/
-DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
const char *ifname = wpa_s->ifname;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &ifname);
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &ifname, error);
}
/**
* wpas_dbus_getter_driver - Get interface name
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a name of network interface
- * driver associated with with wpa_s
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Driver" property.
*/
-DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
const char *driver;
if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
"wpa_s has no driver set");
- return wpas_dbus_error_unknown_error(message, NULL);
+ dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set",
+ __func__);
+ return FALSE;
}
driver = wpa_s->driver->name;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &driver);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &driver, error);
}
/**
* wpas_dbus_getter_current_bss - Get current bss object path
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a DBus object path to
- * current BSS
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "CurrentBSS" property.
*/
-DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply;
+ struct wpa_supplicant *wpa_s = user_data;
char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
if (wpa_s->current_bss)
@@ -2331,27 +2405,25 @@ DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
else
os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
- reply = wpas_dbus_simple_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- &bss_obj_path);
-
- return reply;
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
+ &bss_obj_path, error);
}
/**
* wpas_dbus_getter_current_network - Get current network object path
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a DBus object path to
- * current network
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "CurrentNetwork" property.
*/
-DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply;
+ struct wpa_supplicant *wpa_s = user_data;
char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
if (wpa_s->current_ssid)
@@ -2361,27 +2433,25 @@ DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
else
os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
- reply = wpas_dbus_simple_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- &net_obj_path);
-
- return reply;
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
+ &net_obj_path, error);
}
/**
* wpas_dbus_getter_current_auth_mode - Get current authentication type
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a string indicating the current
- * authentication type.
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "CurrentAuthMode" property.
*/
-DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply;
+ struct wpa_supplicant *wpa_s = user_data;
const char *eap_mode;
const char *auth_mode;
char eap_mode_buf[WPAS_DBUS_AUTH_MODE_MAX];
@@ -2400,70 +2470,61 @@ DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message,
wpa_s->current_ssid->proto);
}
- reply = wpas_dbus_simple_property_getter(message,
- DBUS_TYPE_STRING,
- &auth_mode);
-
- return reply;
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &auth_mode, error);
}
/**
* wpas_dbus_getter_bridge_ifname - Get interface name
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing a name of bridge network
- * interface associated with with wpa_s
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "BridgeIfname" property.
*/
-DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- const char *bridge_ifname = NULL;
-
- bridge_ifname = wpa_s->bridge_ifname;
- if (bridge_ifname == NULL) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
- "wpa_s has no bridge interface name set");
- return wpas_dbus_error_unknown_error(message, NULL);
- }
-
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &bridge_ifname);
+ struct wpa_supplicant *wpa_s = user_data;
+ const char *bridge_ifname = wpa_s->bridge_ifname;
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &bridge_ifname, error);
}
/**
* wpas_dbus_getter_bsss - Get array of BSSs objects
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing an array of all known BSS objects
- * dbus paths
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "BSSs" property.
*/
-DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
struct wpa_bss *bss;
char **paths;
unsigned int i = 0;
+ dbus_bool_t success = FALSE;
paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
if (!paths) {
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
/* 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) {
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
if (paths[i] == NULL) {
- reply = dbus_message_new_error(message,
- DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
goto out;
}
/* Construct the object path for this BSS. */
@@ -2472,39 +2533,43 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
wpa_s->dbus_new_path, bss->id);
}
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- paths, wpa_s->num_bss);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_OBJECT_PATH,
+ paths, wpa_s->num_bss,
+ error);
out:
while (i)
os_free(paths[--i]);
os_free(paths);
- return reply;
+ return success;
}
/**
* wpas_dbus_getter_networks - Get array of networks objects
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing an array of all configured
- * networks dbus object paths.
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Networks" property.
*/
-DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
struct wpa_ssid *ssid;
char **paths;
unsigned int i = 0, num = 0;
+ dbus_bool_t success = FALSE;
if (wpa_s->conf == NULL) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
- "An error occurred getting networks list.");
- return wpas_dbus_error_unknown_error(message, NULL);
+ wpa_printf(MSG_ERROR, "%s[dbus]: An error occurred getting "
+ "networks list.", __func__);
+ dbus_set_error(error, DBUS_ERROR_FAILED, "%s: an error "
+ "occurred getting the networks list", __func__);
+ return FALSE;
}
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
@@ -2513,8 +2578,8 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
paths = os_zalloc(num * sizeof(char *));
if (!paths) {
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
/* Loop through configured networks and append object path of each */
@@ -2523,9 +2588,7 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
continue;
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
if (paths[i] == NULL) {
- reply = dbus_message_new_error(message,
- DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
goto out;
}
@@ -2535,50 +2598,40 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
wpa_s->dbus_new_path, ssid->id);
}
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- paths, num);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_OBJECT_PATH,
+ paths, num, error);
out:
while (i)
os_free(paths[--i]);
os_free(paths);
- return reply;
+ return success;
}
/**
* wpas_dbus_getter_blobs - Get all blobs defined for this interface
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Blobs" property.
*/
-DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
struct wpa_config_blob *blob;
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
-
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{say}", &variant_iter) ||
!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
"{say}", &dict_iter)) {
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
blob = wpa_s->conf->blobs;
@@ -2601,176 +2654,192 @@ DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
&array_iter) ||
!dbus_message_iter_close_container(&dict_iter,
&entry_iter)) {
- dbus_message_unref(reply);
- return dbus_message_new_error(message,
- DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
+ return FALSE;
}
blob = blob->next;
}
if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(&iter, &variant_iter)) {
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ !dbus_message_iter_close_container(iter, &variant_iter)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
- return reply;
+ return TRUE;
+}
+
+
+static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
+ DBusError *error, const char *func_name)
+{
+ struct wpa_bss *res = wpa_bss_get_id(args->wpa_s, args->id);
+
+ if (!res) {
+ wpa_printf(MSG_ERROR, "%s[dbus]: no bss with id %d found",
+ func_name, args->id);
+ dbus_set_error(error, DBUS_ERROR_FAILED,
+ "%s: BSS %d not found",
+ func_name, args->id);
+ }
+
+ return res;
}
/**
* wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the bssid for the requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "BSSID" property.
*/
-DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
- return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
- res->bssid, ETH_ALEN);
+ return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+ res->bssid, ETH_ALEN,
+ error);
}
/**
* wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the ssid for the requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "SSID" property.
*/
-DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
- return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
- res->ssid,
- res->ssid_len);
+ return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+ res->ssid, res->ssid_len,
+ error);
}
/**
* wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the privacy flag value of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Privacy" property.
*/
-DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
dbus_bool_t privacy;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
- &privacy);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+ &privacy, error);
}
/**
* wpas_dbus_getter_bss_mode - Return the mode of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the mode of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Mode" property.
*/
-DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
const char *mode;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
if (res->caps & IEEE80211_CAP_IBSS)
mode = "ad-hoc";
else
mode = "infrastructure";
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &mode);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+ &mode, error);
}
/**
* wpas_dbus_getter_bss_level - Return the signal strength of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the signal strength of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Level" property.
*/
-DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
- &res->level);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16,
+ &res->level, error);
}
/**
* wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the frequency of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Frequency" property.
*/
-DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
- "no bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
- &res->freq);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
+ &res->freq, error);
}
@@ -2782,72 +2851,64 @@ static int cmp_u8s_desc(const void *a, const void *b)
/**
* wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing sorted array of bit rates
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Rates" property.
*/
-DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- DBusMessage *reply;
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
u8 *ie_rates = NULL;
u32 *real_rates;
int rates_num, i;
+ dbus_bool_t success = FALSE;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: "
- "no bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
if (rates_num < 0)
- return NULL;
+ return FALSE;
qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
real_rates = os_malloc(sizeof(u32) * rates_num);
if (!real_rates) {
os_free(ie_rates);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
for (i = 0; i < rates_num; i++)
real_rates[i] = ie_rates[i] * 500000;
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_UINT32,
- real_rates, rates_num);
+ success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_UINT32,
+ real_rates, rates_num,
+ error);
os_free(ie_rates);
os_free(real_rates);
- return reply;
+ return success;
}
-static DBusMessage * wpas_dbus_get_bss_security_prop(
- DBusMessage *message, struct wpa_ie_data *ie_data)
+static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
+ struct wpa_ie_data *ie_data,
+ DBusError *error)
{
- DBusMessage *reply;
- DBusMessageIter iter, iter_dict, variant_iter;
+ DBusMessageIter iter_dict, variant_iter;
const char *group;
const char *pairwise[2]; /* max 2 pairwise ciphers is supported */
const char *key_mgmt[7]; /* max 7 key managements may be supported */
int n;
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
- if (!reply)
- goto nomem;
-
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{sv}", &variant_iter))
goto nomem;
@@ -2928,152 +2989,152 @@ static DBusMessage * wpas_dbus_get_bss_security_prop(
if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
goto nomem;
- if (!dbus_message_iter_close_container(&iter, &variant_iter))
+ if (!dbus_message_iter_close_container(iter, &variant_iter))
goto nomem;
- return reply;
+ return TRUE;
nomem:
- if (reply)
- dbus_message_unref(reply);
-
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
/**
* wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the WPA options of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "WPA" property.
*/
-DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
struct wpa_ie_data wpa_data;
const u8 *ie;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
os_memset(&wpa_data, 0, sizeof(wpa_data));
ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
if (ie) {
- if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0)
- return wpas_dbus_error_unknown_error(message,
- "invalid WPA IE");
+ if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "failed to parse WPA IE");
+ return FALSE;
+ }
}
- return wpas_dbus_get_bss_security_prop(message, &wpa_data);
+ return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error);
}
/**
* wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the RSN options of requested bss
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "RSN" property.
*/
-DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
struct wpa_ie_data wpa_data;
const u8 *ie;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
os_memset(&wpa_data, 0, sizeof(wpa_data));
ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
if (ie) {
- if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0)
- return wpas_dbus_error_unknown_error(message,
- "invalid RSN IE");
+ if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "failed to parse RSN IE");
+ return FALSE;
+ }
}
- return wpas_dbus_get_bss_security_prop(message, &wpa_data);
+ return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error);
}
/**
* wpas_dbus_getter_bss_ies - Return all IEs of a BSS
- * @message: Pointer to incoming dbus message
- * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing IEs byte array
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "IEs" property.
*/
-DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
- struct bss_handler_args *bss)
+dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+ struct bss_handler_args *args = user_data;
+ struct wpa_bss *res;
- if (!res) {
- wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no "
- "bss with id %d found", bss->id);
- return NULL;
- }
+ res = get_bss_helper(args, error, __func__);
+ if (!res)
+ return FALSE;
- return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
- res + 1, res->ie_len);
+ return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+ res + 1, res->ie_len,
+ error);
}
/**
* wpas_dbus_getter_enabled - Check whether network is enabled or disabled
- * @message: Pointer to incoming dbus message
- * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
- * and wpa_ssid structure for a configured network
- * Returns: DBus message with boolean indicating state of configured network
- * or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "enabled" property of a configured network.
*/
-DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
- struct network_handler_args *net)
+dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct network_handler_args *net = user_data;
dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
- &enabled);
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+ &enabled, error);
}
/**
* wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
- * @message: Pointer to incoming dbus message
- * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
- * and wpa_ssid structure for a configured network
- * Returns: NULL indicating success or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "Enabled" property of a configured network.
*/
-DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
- struct network_handler_args *net)
+dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
-
+ struct network_handler_args *net = user_data;
struct wpa_supplicant *wpa_s;
struct wpa_ssid *ssid;
-
dbus_bool_t enable;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
- &enable);
-
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+ &enable))
+ return FALSE;
wpa_s = net->wpa_s;
ssid = net->ssid;
@@ -3083,48 +3144,38 @@ DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
else
wpa_supplicant_disable_network(wpa_s, ssid);
- return NULL;
+ return TRUE;
}
/**
* wpas_dbus_getter_network_properties - Get options for a configured network
- * @message: Pointer to incoming dbus message
- * @net: wpa_supplicant structure for a network interface and
- * wpa_ssid structure for a configured network
- * Returns: DBus message with network properties or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Properties" property of a configured network.
*/
-DBusMessage * wpas_dbus_getter_network_properties(
- DBusMessage *message, struct network_handler_args *net)
+dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter, dict_iter;
+ struct network_handler_args *net = user_data;
+ DBusMessageIter variant_iter, dict_iter;
char **iterator;
char **props = wpa_config_get_all(net->ssid, 1);
- if (!props)
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_bool_t success = FALSE;
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
- if (!reply) {
- reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
- goto out;
+ if (!props) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
- "a{sv}", &variant_iter) ||
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}",
+ &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
- dbus_message_unref(reply);
- reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
goto out;
}
@@ -3132,10 +3183,8 @@ DBusMessage * wpas_dbus_getter_network_properties(
while (*iterator) {
if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
*(iterator + 1))) {
- dbus_message_unref(reply);
- reply = dbus_message_new_error(message,
- DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
goto out;
}
iterator += 2;
@@ -3143,13 +3192,13 @@ DBusMessage * wpas_dbus_getter_network_properties(
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(&iter, &variant_iter)) {
- dbus_message_unref(reply);
- reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ !dbus_message_iter_close_container(iter, &variant_iter)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
goto out;
}
+ success = TRUE;
+
out:
iterator = props;
while (*iterator) {
@@ -3157,39 +3206,27 @@ out:
iterator++;
}
os_free(props);
- return reply;
+ return success;
}
/**
* wpas_dbus_setter_network_properties - Set options for a configured network
- * @message: Pointer to incoming dbus message
- * @net: wpa_supplicant structure for a network interface and
- * wpa_ssid structure for a configured network
- * Returns: NULL indicating success or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "Properties" property of a configured network.
*/
-DBusMessage * wpas_dbus_setter_network_properties(
- DBusMessage *message, struct network_handler_args *net)
+dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
+ struct network_handler_args *net = user_data;
struct wpa_ssid *ssid = net->ssid;
+ DBusMessageIter variant_iter;
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter;
-
- dbus_message_iter_init(message, &iter);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_next(&iter);
-
- dbus_message_iter_recurse(&iter, &variant_iter);
-
- reply = set_network_properties(message, net->wpa_s, ssid,
- &variant_iter);
- if (reply)
- wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
- "network properties");
-
- return reply;
+ dbus_message_iter_recurse(iter, &variant_iter);
+ return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 978ee4c..ac3af1f 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -26,17 +26,20 @@ struct bss_handler_args {
unsigned int id;
};
-DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message,
- const int type,
- const void *val);
+dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
+ const int type,
+ const void *val,
+ DBusError *error);
-DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message,
- const int type, void *val);
+dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
+ DBusError *error,
+ const int type, void *val);
-DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message,
- const int type,
- const void *array,
- size_t array_len);
+dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
+ const int type,
+ const void *array,
+ size_t array_len,
+ DBusError *error);
DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
struct wpa_global *global);
@@ -47,29 +50,35 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
struct wpa_global *global);
-DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
- struct wpa_global *global);
+dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message,
- void *nothing);
+dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
struct wpa_supplicant *wpa_s);
@@ -77,10 +86,10 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
struct wpa_supplicant *wpa_s);
-DBusMessage * set_network_properties(DBusMessage *message,
- struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- DBusMessageIter *iter);
+dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ DBusMessageIter *iter,
+ DBusError *error);
DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
struct wpa_supplicant *wpa_s);
@@ -94,6 +103,9 @@ DBusMessage * wpas_dbus_handler_remove_all_networks(
DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
struct wpa_supplicant *wpa_s);
@@ -106,119 +118,126 @@ DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_country(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_country(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
- struct wpa_supplicant *bss);
+dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
- struct bss_handler_args *bss);
+dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
- struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
- struct network_handler_args *net);
+dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_getter_network_properties(
- DBusMessage *message, struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage * wpas_dbus_setter_network_properties(
- DBusMessage *message, struct network_handler_args *net);
+dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_getter_process_credentials(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_setter_process_credentials(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
-DBusMessage * wpas_dbus_getter_credentials(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
const char *arg);
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 55482b4..671d0e5 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -70,23 +70,23 @@ static DBusMessage * wpas_dbus_error_persistent_group_unknown(
}
-DBusMessage *wpas_dbus_handler_p2p_find(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
struct wpa_dbus_dict_entry entry;
DBusMessage *reply = NULL;
DBusMessageIter iter;
DBusMessageIter iter_dict;
unsigned int timeout = 0;
- unsigned int searchonly = 0;
enum p2p_discovery_type type = P2P_FIND_ONLY_SOCIAL;
int num_req_dev_types = 0;
unsigned int i;
u8 *req_dev_types = NULL;
dbus_message_iter_init(message, &iter);
+ entry.key = NULL;
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@@ -96,14 +96,12 @@ DBusMessage *wpas_dbus_handler_p2p_find(DBusMessage * message,
if (!os_strcmp(entry.key, "Timeout") &&
(entry.type == DBUS_TYPE_INT32)) {
timeout = entry.uint32_value;
- } else if (!os_strcmp(entry.key, "SearchOnly") &&
- (entry.type == DBUS_TYPE_BOOLEAN)) {
- searchonly = (entry.bool_value == TRUE) ? 1 : 0;
} else if (os_strcmp(entry.key, "RequestedDeviceTypes") == 0) {
if ((entry.type != DBUS_TYPE_ARRAY) ||
(entry.array_type != WPAS_DBUS_TYPE_BINARRAY))
goto error_clear;
+ os_free(req_dev_types);
req_dev_types =
os_malloc(WPS_DEV_TYPE_LEN * entry.array_len);
if (!req_dev_types)
@@ -117,33 +115,45 @@ DBusMessage *wpas_dbus_handler_p2p_find(DBusMessage * message,
wpabuf_head(entry.binarray_value[i]),
WPS_DEV_TYPE_LEN);
}
-
num_req_dev_types = entry.array_len;
+ } else if (!os_strcmp(entry.key, "DiscoveryType") &&
+ (entry.type == DBUS_TYPE_STRING)) {
+ if (!os_strcmp(entry.str_value, "start_with_full"))
+ type = P2P_FIND_START_WITH_FULL;
+ else if (!os_strcmp(entry.str_value, "social"))
+ type = P2P_FIND_ONLY_SOCIAL;
+ else if (!os_strcmp(entry.str_value, "progressive"))
+ type = P2P_FIND_PROGRESSIVE;
+ else
+ goto error_clear;
} else
goto error_clear;
wpa_dbus_dict_entry_clear(&entry);
}
wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types);
+ os_free(req_dev_types);
return reply;
error_clear:
- os_free(req_dev_types);
wpa_dbus_dict_entry_clear(&entry);
error:
+ os_free(req_dev_types);
reply = wpas_dbus_error_invalid_args(message, entry.key);
return reply;
}
-DBusMessage *wpas_dbus_handler_p2p_stop_find(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
wpas_p2p_stop_find(wpa_s);
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_rejectpeer(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter;
char *peer_object_path = NULL;
@@ -162,8 +172,9 @@ DBusMessage *wpas_dbus_handler_p2p_rejectpeer(DBusMessage * message,
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_listen(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
dbus_int32_t timeout = 0;
@@ -179,8 +190,9 @@ DBusMessage *wpas_dbus_handler_p2p_listen(DBusMessage * message,
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_extendedlisten(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_extendedlisten(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
unsigned int period = 0, interval = 0;
struct wpa_dbus_dict_entry entry;
@@ -188,18 +200,19 @@ DBusMessage *wpas_dbus_handler_p2p_extendedlisten(DBusMessage * message,
DBusMessageIter iter_dict;
dbus_message_iter_init(message, &iter);
+ entry.key = NULL;
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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, "period") &&
+ if (!os_strcmp(entry.key, "period") &&
(entry.type == DBUS_TYPE_INT32))
period = entry.uint32_value;
- else if (!strcmp(entry.key, "interval") &&
+ else if (!os_strcmp(entry.key, "interval") &&
(entry.type == DBUS_TYPE_INT32))
interval = entry.uint32_value;
else
@@ -208,8 +221,8 @@ DBusMessage *wpas_dbus_handler_p2p_extendedlisten(DBusMessage * message,
}
if (wpas_p2p_ext_listen(wpa_s, period, interval))
- return wpas_dbus_error_unknown_error(message,
- "failed to initiate a p2p_ext_listen.");
+ return wpas_dbus_error_unknown_error(
+ message, "failed to initiate a p2p_ext_listen.");
return NULL;
@@ -219,9 +232,9 @@ error:
return wpas_dbus_error_invalid_args(message, entry.key);
}
-DBusMessage *wpas_dbus_handler_p2p_presence_request(DBusMessage * message,
- struct wpa_supplicant *
- wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_presence_request(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
struct wpa_dbus_dict_entry entry;
@@ -229,24 +242,25 @@ DBusMessage *wpas_dbus_handler_p2p_presence_request(DBusMessage * message,
DBusMessageIter iter_dict;
dbus_message_iter_init(message, &iter);
+ entry.key = NULL;
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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, "duration1") &&
+ if (!os_strcmp(entry.key, "duration1") &&
(entry.type == DBUS_TYPE_INT32))
dur1 = entry.uint32_value;
- else if (!strcmp(entry.key, "interval1") &&
+ else if (!os_strcmp(entry.key, "interval1") &&
entry.type == DBUS_TYPE_INT32)
int1 = entry.uint32_value;
- else if (!strcmp(entry.key, "duration2") &&
+ else if (!os_strcmp(entry.key, "duration2") &&
entry.type == DBUS_TYPE_INT32)
dur2 = entry.uint32_value;
- else if (!strcmp(entry.key, "interval2") &&
+ else if (!os_strcmp(entry.key, "interval2") &&
entry.type == DBUS_TYPE_INT32)
int2 = entry.uint32_value;
else
@@ -266,8 +280,9 @@ error:
return wpas_dbus_error_invalid_args(message, entry.key);
}
-DBusMessage *wpas_dbus_handler_p2p_group_add(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
DBusMessage *reply = NULL;
@@ -283,22 +298,22 @@ DBusMessage *wpas_dbus_handler_p2p_group_add(DBusMessage * message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto inv_args;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto inv_args;
- if (!strcmp(entry.key, "persistent") &&
+ if (!os_strcmp(entry.key, "persistent") &&
(entry.type == DBUS_TYPE_BOOLEAN)) {
persistent_group = (entry.bool_value == TRUE) ? 1 : 0;
- } else if (!strcmp(entry.key, "frequency") &&
+ } else if (!os_strcmp(entry.key, "frequency") &&
(entry.type == DBUS_TYPE_INT32)) {
freq = entry.int32_value;
if (freq <= 0)
goto inv_args_clear;
- } else if (!strcmp(entry.key, "persistent_group_object") &&
+ } else if (!os_strcmp(entry.key, "persistent_group_object") &&
entry.type == DBUS_TYPE_OBJECT_PATH)
pg_object_path = os_strdup(entry.str_value);
else
@@ -330,14 +345,15 @@ DBusMessage *wpas_dbus_handler_p2p_group_add(DBusMessage * message,
goto out;
}
- /* Get the SSID structure form the persistant group id */
+ /* Get the SSID structure from the persistent group id */
ssid = wpa_config_get_network(wpa_s->conf, group_id);
if (ssid == NULL || ssid->disabled != 2)
goto inv_args;
if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq)) {
- reply = wpas_dbus_error_unknown_error(message,
- "Failed to reinvoke a persistent group");
+ reply = wpas_dbus_error_unknown_error(
+ message,
+ "Failed to reinvoke a persistent group");
goto out;
}
} else if (wpas_p2p_group_add(wpa_s, persistent_group, freq))
@@ -355,8 +371,9 @@ inv_args:
goto out;
}
-DBusMessage *wpas_dbus_handler_p2p_disconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_disconnect(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
if (wpas_p2p_disconnect(wpa_s))
return wpas_dbus_error_unknown_error(message,
@@ -365,9 +382,36 @@ DBusMessage *wpas_dbus_handler_p2p_disconnect(DBusMessage *message,
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_flush(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+static dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s,
+ DBusMessage *message,
+ DBusMessage **out_reply,
+ DBusError *error)
{
+ /* Return an error message or an error if P2P isn't available */
+ if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
+ if (out_reply) {
+ *out_reply = dbus_message_new_error(
+ message, DBUS_ERROR_FAILED,
+ "P2P is not available for this interface");
+ }
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "P2P is not available for this "
+ "interface");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+DBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+
+ if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
+ return reply;
+
os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
wpa_s->force_long_sd = 0;
p2p_flush(wpa_s->global->p2p);
@@ -375,8 +419,9 @@ DBusMessage *wpas_dbus_handler_p2p_flush(DBusMessage * message,
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
DBusMessage *reply = NULL;
@@ -395,52 +440,53 @@ DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message,
char *err_msg = NULL;
char *iface = NULL;
+ if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
+ return reply;
+
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto inv_args;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto inv_args;
- if (!strcmp(entry.key, "peer") &&
+ if (!os_strcmp(entry.key, "peer") &&
(entry.type == DBUS_TYPE_OBJECT_PATH)) {
peer_object_path = os_strdup(entry.str_value);
- } else if (!strcmp(entry.key, "persistent") &&
+ } else if (!os_strcmp(entry.key, "persistent") &&
(entry.type == DBUS_TYPE_BOOLEAN)) {
persistent_group = (entry.bool_value == TRUE) ? 1 : 0;
- } else if (!strcmp(entry.key, "join") &&
+ } else if (!os_strcmp(entry.key, "join") &&
(entry.type == DBUS_TYPE_BOOLEAN)) {
join = (entry.bool_value == TRUE) ? 1 : 0;
- } else if (!strcmp(entry.key, "authorize_only") &&
+ } else if (!os_strcmp(entry.key, "authorize_only") &&
(entry.type == DBUS_TYPE_BOOLEAN)) {
authorize_only = (entry.bool_value == TRUE) ? 1 : 0;
- } else if (!strcmp(entry.key, "frequency") &&
+ } else if (!os_strcmp(entry.key, "frequency") &&
(entry.type == DBUS_TYPE_INT32)) {
freq = entry.int32_value;
if (freq <= 0)
goto inv_args_clear;
- } else if (!strcmp(entry.key, "go_intent") &&
+ } else if (!os_strcmp(entry.key, "go_intent") &&
(entry.type == DBUS_TYPE_INT32)) {
go_intent = entry.int32_value;
if ((go_intent < 0) || (go_intent > 15))
goto inv_args_clear;
- } else if (!strcmp(entry.key, "wps_method") &&
+ } else if (!os_strcmp(entry.key, "wps_method") &&
(entry.type == DBUS_TYPE_STRING)) {
- if (!strcmp(entry.str_value, "pbc"))
+ if (!os_strcmp(entry.str_value, "pbc"))
wps_method = WPS_PBC;
- else if (!strcmp(entry.str_value, "pin"))
+ else if (!os_strcmp(entry.str_value, "pin"))
wps_method = WPS_PIN_DISPLAY;
- else if (!strcmp(entry.str_value, "label"))
- wps_method = WPS_PIN_LABEL;
- else if (!strcmp(entry.str_value, "display"))
+ else if (!os_strcmp(entry.str_value, "display"))
wps_method = WPS_PIN_DISPLAY;
- else if (!strcmp(entry.str_value, "keypad"))
+ else if (!os_strcmp(entry.str_value, "keypad"))
wps_method = WPS_PIN_KEYPAD;
else
goto inv_args_clear;
- } else if (!strcmp(entry.key, "pin") &&
+ } else if (!os_strcmp(entry.key, "pin") &&
(entry.type == DBUS_TYPE_STRING)) {
pin = os_strdup(entry.str_value);
} else
@@ -451,16 +497,13 @@ DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message,
if (!peer_object_path || (wps_method == WPS_NOT_READY) ||
(parse_peer_object_path(peer_object_path, addr) < 0) ||
- (p2p_get_peer_info(wpa_s->global->p2p, addr, 0, NULL, 0) < 0)) {
- reply = wpas_dbus_error_invalid_args(message, NULL);
+ !p2p_peer_known(wpa_s->global->p2p, addr))
goto inv_args;
- }
/*
* Validate the wps_method specified and the pin value.
*/
- if ((!pin || !pin[0]) &&
- ((wps_method == WPS_PIN_LABEL) || (wps_method == WPS_PIN_KEYPAD)))
+ if ((!pin || !pin[0]) && (wps_method == WPS_PIN_KEYPAD))
goto inv_args;
new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
@@ -468,31 +511,34 @@ DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message,
go_intent, freq);
if (new_pin >= 0) {
+ char npin[9];
+ char *generated_pin;
+ os_snprintf(npin, sizeof(npin), "%08d", new_pin);
+ generated_pin = npin;
reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_INT32,
- &new_pin, DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING,
+ &generated_pin, DBUS_TYPE_INVALID);
} else {
switch (new_pin) {
case -2:
- err_msg = "connect failed due to"
- " channel unavailability.";
+ err_msg = "connect failed due to channel "
+ "unavailability.";
iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE;
break;
case -3:
- err_msg = "connect failed due to"
- " unsupported channel.";
+ err_msg = "connect failed due to unsupported channel.";
iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNSUPPORTED;
break;
default:
- err_msg = "connect failed due to"
- " unspecified error.";
+ err_msg = "connect failed due to unspecified error.";
iface = WPAS_DBUS_ERROR_CONNECT_UNSPECIFIED_ERROR;
break;
}
+
/*
- * TODO::
+ * TODO:
* Do we need specialized errors corresponding to above
* error conditions as against just returning a different
* error message?
@@ -511,8 +557,9 @@ inv_args:
goto out;
}
-DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message,
- struct wpa_supplicant *wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
DBusMessage *reply = NULL;
@@ -527,20 +574,23 @@ DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message,
int persistent = 0;
struct wpa_ssid *ssid;
+ if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
+ return reply;
+
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto err;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto err;
- if (!strcmp(entry.key, "peer") &&
+ if (!os_strcmp(entry.key, "peer") &&
(entry.type == DBUS_TYPE_OBJECT_PATH)) {
peer_object_path = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
- } else if (!strcmp(entry.key, "persistent_group_object") &&
+ } else if (!os_strcmp(entry.key, "persistent_group_object") &&
(entry.type == DBUS_TYPE_OBJECT_PATH)) {
pg_object_path = os_strdup(entry.str_value);
persistent = 1;
@@ -553,43 +603,41 @@ DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message,
if (!peer_object_path ||
(parse_peer_object_path(peer_object_path, peer_addr) < 0) ||
- (p2p_get_peer_info(wpa_s->global->p2p,
- peer_addr, 0, NULL, 0) < 0)) {
+ !p2p_peer_known(wpa_s->global->p2p, peer_addr)) {
goto err;
}
if (persistent) {
/*
* A group ID is defined meaning we want to re-invoke a
- * persisatnt group
+ * persistent group
*/
iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1,
&net_id_str, NULL);
if (iface == NULL ||
os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
- reply =
- wpas_dbus_error_invalid_args(message,
- pg_object_path);
+ reply = wpas_dbus_error_invalid_args(message,
+ pg_object_path);
goto out;
}
group_id = strtoul(net_id_str, NULL, 10);
if (errno == EINVAL) {
reply = wpas_dbus_error_invalid_args(
- message, pg_object_path);
+ message, pg_object_path);
goto out;
}
- /* Get the SSID structure form the persistant group id */
+ /* Get the SSID structure from the persistent group id */
ssid = wpa_config_get_network(wpa_s->conf, group_id);
if (ssid == NULL || ssid->disabled != 2)
goto err;
if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL) < 0) {
reply = wpas_dbus_error_unknown_error(
- message,
- "Failed to reinvoke a persistent group");
+ message,
+ "Failed to reinvoke a persistent group");
goto out;
}
} else {
@@ -597,10 +645,9 @@ DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message,
* No group ID means propose to a peer to join my active group
*/
if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname,
- peer_addr, NULL)) {
+ peer_addr, NULL)) {
reply = wpas_dbus_error_unknown_error(
- message,
- "Failed to join to an active group");
+ message, "Failed to join to an active group");
goto out;
}
}
@@ -615,8 +662,9 @@ err:
goto out;
}
-DBusMessage *wpas_dbus_handler_p2p_prov_disc_req(DBusMessage * message,
- struct wpa_supplicant *wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter;
char *peer_object_path = NULL;
@@ -643,23 +691,24 @@ DBusMessage *wpas_dbus_handler_p2p_prov_disc_req(DBusMessage * message,
os_strcmp(config_method, "pushbutton"))
return wpas_dbus_error_invalid_args(message, NULL);
- if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method) < 0)
+ if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method, 0) < 0)
return wpas_dbus_error_unknown_error(message,
"Failed to send provision discovery request");
return NULL;
}
+
/*
* P2P Device property accessor methods.
*/
-DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message,
- struct wpa_supplicant *
- wpa_s)
+dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter, dict_iter;
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, dict_iter;
DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
iter_secdev_dict_array;
const char *dev_name;
@@ -667,17 +716,10 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message,
int i;
const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT];
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
+ if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
+ return FALSE;
- if (!reply)
- goto err_no_mem;
-
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{sv}", &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
goto err_no_mem;
@@ -738,7 +780,7 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message,
wpa_s->conf->p2p_go_intent))
goto err_no_mem;
- /* Persistant Reconnect */
+ /* Persistent Reconnect */
if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistantReconnect",
wpa_s->conf->persistent_reconnect))
goto err_no_mem;
@@ -785,44 +827,45 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message,
goto err_no_mem;
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(&iter, &variant_iter))
+ !dbus_message_iter_close_container(iter, &variant_iter))
goto err_no_mem;
- return reply;
+ return TRUE;
+
err_no_mem:
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
-DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
- struct wpa_supplicant *
- wpa_s)
+
+dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter;
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, iter_dict;
struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING };
- DBusMessageIter iter_dict;
unsigned int i;
- dbus_message_iter_init(message, &iter);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_next(&iter);
+ if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
+ return FALSE;
- dbus_message_iter_recurse(&iter, &variant_iter);
-
- if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict))
- return wpas_dbus_error_invalid_args(message, NULL);
+ dbus_message_iter_recurse(iter, &variant_iter);
+ if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
+ return FALSE;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- return wpas_dbus_error_invalid_args(message, NULL);
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
+ }
if (os_strcmp(entry.key, "DeviceName") == 0) {
char *devname;
if (entry.type != DBUS_TYPE_STRING)
- goto error_clear;
+ goto error;
devname = os_strdup(entry.str_value);
if (devname == NULL)
@@ -832,12 +875,12 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
wpa_s->conf->device_name = devname;
wpa_s->conf->changed_parameters |=
- CFG_CHANGED_DEVICE_NAME;
+ CFG_CHANGED_DEVICE_NAME;
} else if (os_strcmp(entry.key, "PrimaryDeviceType") == 0) {
if (entry.type != DBUS_TYPE_ARRAY ||
entry.array_type != DBUS_TYPE_BYTE ||
entry.array_len != WPS_DEV_TYPE_LEN)
- goto error_clear;
+ goto error;
os_memcpy(wpa_s->conf->device_type,
entry.bytearray_value,
@@ -851,7 +894,8 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
goto error;
for (i = 0; i < entry.array_len; i++)
- if (wpabuf_len(entry.binarray_value[i]) != WPS_DEV_TYPE_LEN)
+ if (wpabuf_len(entry.binarray_value[i]) !=
+ WPS_DEV_TYPE_LEN)
goto err_no_mem_clear;
for (i = 0; i < entry.array_len; i++)
os_memcpy(wpa_s->conf->sec_device_type[i],
@@ -864,10 +908,10 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
if ((entry.type != DBUS_TYPE_ARRAY) ||
(entry.array_type != WPAS_DBUS_TYPE_BINARRAY) ||
(entry.array_len > P2P_MAX_WPS_VENDOR_EXT))
- goto error_clear;
+ goto error;
wpa_s->conf->changed_parameters |=
- CFG_CHANGED_VENDOR_EXTENSION;
+ CFG_CHANGED_VENDOR_EXTENSION;
for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
wpabuf_free(wpa_s->conf->wps_vendor_ext[i]);
@@ -882,11 +926,9 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
(entry.type == DBUS_TYPE_UINT32) &&
(entry.uint32_value <= 15))
wpa_s->conf->p2p_go_intent = entry.uint32_value;
-
else if ((os_strcmp(entry.key, "PersistantReconnect") == 0) &&
(entry.type == DBUS_TYPE_BOOLEAN))
wpa_s->conf->persistent_reconnect = entry.bool_value;
-
else if ((os_strcmp(entry.key, "ListenRegClass") == 0) &&
(entry.type == DBUS_TYPE_UINT32)) {
wpa_s->conf->p2p_listen_reg_class = entry.uint32_value;
@@ -911,7 +953,7 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
char *postfix;
if (entry.type != DBUS_TYPE_STRING)
- goto error_clear;
+ goto error;
postfix = os_strdup(entry.str_value);
if (!postfix)
@@ -926,7 +968,7 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
(entry.type == DBUS_TYPE_BOOLEAN)) {
wpa_s->conf->p2p_intra_bss = entry.bool_value;
wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_INTRA_BSS;
+ CFG_CHANGED_P2P_INTRA_BSS;
} else if ((os_strcmp(entry.key, "GroupIdle") == 0) &&
(entry.type == DBUS_TYPE_UINT32))
wpa_s->conf->p2p_group_idle = entry.uint32_value;
@@ -934,7 +976,7 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
entry.type == DBUS_TYPE_UINT32)
wpa_s->conf->disassoc_low_ack = entry.uint32_value;
else
- goto error_clear;
+ goto error;
wpa_dbus_dict_entry_clear(&entry);
}
@@ -944,29 +986,31 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message,
wpa_supplicant_update_config(wpa_s);
}
- return reply;
+ return TRUE;
- error_clear:
- wpa_dbus_dict_entry_clear(&entry);
error:
- reply = wpas_dbus_error_invalid_args(message, entry.key);
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
wpa_dbus_dict_entry_clear(&entry);
+ return FALSE;
- return reply;
err_no_mem_clear:
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
wpa_dbus_dict_entry_clear(&entry);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
}
-DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
struct p2p_data *p2p = wpa_s->global->p2p;
int next = 0, i = 0;
int num = 0, out_of_mem = 0;
const u8 *addr;
const struct p2p_peer_info *peer_info = NULL;
+ dbus_bool_t success = FALSE;
struct dl_list peer_objpath_list;
struct peer_objpath_node {
@@ -976,6 +1020,9 @@ DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage * message,
char **peer_obj_paths = NULL;
+ if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
+ return FALSE;
+
dl_list_init(&peer_objpath_list);
/* Get the first peer info */
@@ -1016,9 +1063,10 @@ DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage * message,
struct peer_objpath_node, list)
peer_obj_paths[i++] = node->path;
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- peer_obj_paths, num);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_OBJECT_PATH,
+ peer_obj_paths, num,
+ error);
error:
if (peer_obj_paths)
@@ -1030,12 +1078,12 @@ error:
os_free(node);
}
if (out_of_mem)
- reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return reply;
+ return success;
}
+
enum wpas_p2p_role {
WPAS_P2P_ROLE_DEVICE,
WPAS_P2P_ROLE_GO,
@@ -1064,9 +1112,11 @@ static enum wpas_p2p_role wpas_get_p2p_role(struct wpa_supplicant *wpa_s)
}
}
-DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
char *str;
switch (wpas_get_p2p_role(wpa_s)) {
@@ -1080,83 +1130,85 @@ DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage * message,
str = "device";
}
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
- &str);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str,
+ error);
}
-DBusMessage *wpas_dbus_getter_p2p_group(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
+
if (wpa_s->dbus_groupobj_path == NULL)
- return NULL;
+ return FALSE;
- return wpas_dbus_simple_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- &wpa_s->dbus_groupobj_path);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
+ &wpa_s->dbus_groupobj_path,
+ error);
}
-DBusMessage *wpas_dbus_getter_p2p_peergo(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT)
- return NULL;
+ return FALSE;
os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
path = go_peer_obj_path;
- return wpas_dbus_simple_property_getter(message,
- DBUS_TYPE_OBJECT_PATH, &path);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
+ &path, error);
}
+
/*
* Peer object properties accessor methods
*/
-DBusMessage *wpas_dbus_getter_p2p_peer_properties(DBusMessage * message,
- struct peer_handler_args *
- peer_args)
+dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter, dict_iter;
+ struct peer_handler_args *peer_args = user_data;
+ DBusMessageIter variant_iter, dict_iter;
const struct p2p_peer_info *info = NULL;
- char devtype[WPS_DEV_TYPE_BUFSIZE];
+ const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
+ int i, num;
+
+ if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
+ return FALSE;
/* get the peer info */
info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
peer_args->p2p_device_addr, 0);
- if (info == NULL)
- return NULL;
-
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
-
- if (!reply)
- goto err_no_mem;
+ if (info == NULL) {
+ dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
+ return FALSE;
+ }
- dbus_message_iter_init_append(reply, &iter);
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{sv}", &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
goto err_no_mem;
/* Fill out the dictionary */
- wps_dev_type_bin2str(info->pri_dev_type, devtype, sizeof(devtype));
if (!wpa_dbus_dict_append_string(&dict_iter, "DeviceName",
info->device_name))
goto err_no_mem;
- if (!wpa_dbus_dict_append_string(&dict_iter, "PrimaryDeviceType",
- devtype))
+ if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType",
+ (char *)info->pri_dev_type,
+ WPS_DEV_TYPE_LEN))
goto err_no_mem;
if (!wpa_dbus_dict_append_uint16(&dict_iter, "config_method",
info->config_methods))
goto err_no_mem;
if (!wpa_dbus_dict_append_int32(&dict_iter, "level",
- info->level))
+ info->level))
goto err_no_mem;
if (!wpa_dbus_dict_append_byte(&dict_iter, "devicecapability",
info->dev_capab))
@@ -1166,115 +1218,97 @@ DBusMessage *wpas_dbus_getter_p2p_peer_properties(DBusMessage * message,
goto err_no_mem;
if (info->wps_sec_dev_type_list_len) {
- char *sec_dev_types[MAX_SEC_DEVICE_TYPES];
- u8 *sec_dev_type_list = NULL;
- char secdevtype[WPS_DEV_TYPE_BUFSIZE];
- int num_sec_dev_types = 0;
- int i;
-
- sec_dev_type_list = os_zalloc(info->wps_sec_dev_type_list_len);
-
- if (sec_dev_type_list == NULL)
- goto err_no_mem;
-
- os_memcpy(sec_dev_type_list, info->wps_sec_dev_type_list,
- info->wps_sec_dev_type_list_len);
-
- for (i = 0; i < MAX_SEC_DEVICE_TYPES &&
- i < (int) (info->wps_sec_dev_type_list_len /
- WPS_DEV_TYPE_LEN);
- i++) {
- sec_dev_types[i] = os_zalloc(sizeof(secdevtype));
-
- if (!sec_dev_types[i] ||
- wps_dev_type_bin2str(
- &sec_dev_type_list[i *
- WPS_DEV_TYPE_LEN],
- sec_dev_types[i],
- sizeof(secdevtype)) == NULL) {
- while (--i >= 0)
- os_free(sec_dev_types[i]);
- os_free(sec_dev_type_list);
- goto err_no_mem;
- }
-
- num_sec_dev_types++;
- }
-
- os_free(sec_dev_type_list);
+ const u8 *sec_dev_type_list = info->wps_sec_dev_type_list;
+ int num_sec_dev_types =
+ info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN;
+ DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
+ iter_secdev_dict_array;
if (num_sec_dev_types) {
- if (!wpa_dbus_dict_append_string_array(&dict_iter,
+ if (!wpa_dbus_dict_begin_array(&dict_iter,
"SecondaryDeviceTypes",
- (const char **)sec_dev_types,
- num_sec_dev_types)) {
- for (i = 0; i < num_sec_dev_types; i++)
- os_free(sec_dev_types[i]);
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_BYTE_AS_STRING,
+ &iter_secdev_dict_entry,
+ &iter_secdev_dict_val,
+ &iter_secdev_dict_array))
goto err_no_mem;
+ for (i = 0; i < num_sec_dev_types; i++) {
+ wpa_dbus_dict_bin_array_add_element(
+ &iter_secdev_dict_array,
+ sec_dev_type_list,
+ WPS_DEV_TYPE_LEN);
+ sec_dev_type_list += WPS_DEV_TYPE_LEN;
}
- for (i = 0; i < num_sec_dev_types; i++)
- os_free(sec_dev_types[i]);
+ if (!wpa_dbus_dict_end_array(&dict_iter,
+ &iter_secdev_dict_entry,
+ &iter_secdev_dict_val,
+ &iter_secdev_dict_array))
+ goto err_no_mem;
}
}
- {
- /* Add WPS vendor extensions attribute */
- const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
- int i, num = 0;
-
- for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
- if (info->wps_vendor_ext[i] == NULL)
- continue;
- vendor_extension[num] = info->wps_vendor_ext[i];
- num++;
- }
-
- if (!wpa_dbus_dict_append_wpabuf_array(
- &dict_iter, "VendorExtension",
- vendor_extension, num))
- goto err_no_mem;
+ /* Add WPS vendor extensions attribute */
+ for (i = 0, num = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
+ if (info->wps_vendor_ext[i] == NULL)
+ continue;
+ vendor_extension[num] = info->wps_vendor_ext[i];
+ num++;
}
+ if (!wpa_dbus_dict_append_wpabuf_array(&dict_iter, "VendorExtension",
+ vendor_extension, num))
+ goto err_no_mem;
+
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(&iter, &variant_iter))
+ !dbus_message_iter_close_container(iter, &variant_iter))
goto err_no_mem;
- return reply;
+ return TRUE;
+
err_no_mem:
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
-DBusMessage *wpas_dbus_getter_p2p_peer_ies(DBusMessage * message,
- struct peer_handler_args * peer_args)
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
+ DBusError *error, void *user_data)
{
- return NULL;
+ /* struct peer_handler_args *peer_args = user_data; */
+
+ dbus_set_error_const(error, DBUS_ERROR_FAILED, "not implemented");
+ return FALSE;
}
/**
- * wpas_dbus_getter_persistent_groups - Get array of peristent group objects
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: a dbus message containing an array of all persistent group
- * dbus object paths.
+ * wpas_dbus_getter_persistent_groups - Get array of persistent group objects
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
- * Getter for "Networks" property.
+ * Getter for "PersistentGroups" property.
*/
-DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
struct wpa_ssid *ssid;
char **paths;
unsigned int i = 0, num = 0;
+ dbus_bool_t success = FALSE;
if (wpa_s->conf == NULL) {
wpa_printf(MSG_ERROR, "dbus: %s: "
"An error occurred getting persistent groups list",
__func__);
- return wpas_dbus_error_unknown_error(message, NULL);
+ dbus_set_error_const(error, DBUS_ERROR_FAILED, "an error "
+ "occurred getting persistent groups list");
+ return FALSE;
}
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
@@ -1283,8 +1317,8 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
paths = os_zalloc(num * sizeof(char *));
if (!paths) {
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
/* Loop through configured networks and append object path of each */
@@ -1293,9 +1327,8 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
continue;
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
if (paths[i] == NULL) {
- reply = dbus_message_new_error(message,
- DBUS_ERROR_NO_MEMORY,
- NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
goto out;
}
/* Construct the object path for this network. */
@@ -1304,74 +1337,65 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
wpa_s->dbus_new_path, ssid->id);
}
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- paths, num);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_OBJECT_PATH,
+ paths, num, error);
out:
while (i)
os_free(paths[--i]);
os_free(paths);
- return reply;
+ return success;
}
/**
* wpas_dbus_getter_persistent_group_properties - Get options for a persistent
* group
- * @message: Pointer to incoming dbus message
- * @net: wpa_supplicant structure for a network interface and
- * wpa_ssid structure for a configured persistent group (internally network)
- * Returns: DBus message with network properties or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "Properties" property of a persistent group.
*/
-DBusMessage * wpas_dbus_getter_persistent_group_properties(
- DBusMessage *message, struct network_handler_args *net)
+dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- /*
- * Leveraging the fact that persistent group object is still
+ struct network_handler_args *net = user_data;
+
+ /* Leveraging the fact that persistent group object is still
* represented in same manner as network within.
*/
- return wpas_dbus_getter_network_properties(message, net);
+ return wpas_dbus_getter_network_properties(iter, error, net);
}
/**
* wpas_dbus_setter_persistent_group_properties - Get options for a persistent
* group
- * @message: Pointer to incoming dbus message
- * @net: wpa_supplicant structure for a network interface and
- * wpa_ssid structure for a configured persistent group (internally network)
- * Returns: DBus message with network properties or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "Properties" property of a persistent group.
*/
-DBusMessage * wpas_dbus_setter_persistent_group_properties(
- DBusMessage *message, struct network_handler_args *net)
+dbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
+ struct network_handler_args *net = user_data;
struct wpa_ssid *ssid = net->ssid;
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter;
-
- dbus_message_iter_init(message, &iter);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_next(&iter);
-
- dbus_message_iter_recurse(&iter, &variant_iter);
+ DBusMessageIter variant_iter;
/*
* Leveraging the fact that persistent group object is still
* represented in same manner as network within.
*/
- reply = set_network_properties(message, net->wpa_s, ssid,
- &variant_iter);
- if (reply)
- wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
- "persistent group properties");
-
- return reply;
+ dbus_message_iter_recurse(iter, &variant_iter);
+ return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
}
@@ -1393,6 +1417,7 @@ DBusMessage * wpas_dbus_handler_add_persistent_group(
DBusMessageIter iter;
struct wpa_ssid *ssid = NULL;
char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
+ DBusError error;
dbus_message_iter_init(message, &iter);
@@ -1414,11 +1439,16 @@ DBusMessage * wpas_dbus_handler_add_persistent_group(
wpa_config_set_network_defaults(ssid);
- reply = set_network_properties(message, wpa_s, ssid, &iter);
- if (reply) {
+ dbus_error_init(&error);
+ if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
wpa_printf(MSG_DEBUG, "dbus: %s: "
"Control interface could not set persistent group "
"properties", __func__);
+ reply = wpas_dbus_reply_new_from_error(message, &error,
+ DBUS_ERROR_INVALID_ARGS,
+ "Failed to set network "
+ "properties");
+ dbus_error_free(&error);
goto err;
}
@@ -1564,27 +1594,29 @@ DBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
* Group object properties accessor methods
*/
-DBusMessage *wpas_dbus_getter_p2p_group_members(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
struct wpa_ssid *ssid;
unsigned int num_members;
char **paths;
unsigned int i;
void *next = NULL;
const u8 *addr;
+ dbus_bool_t success = FALSE;
/* Ensure we are a GO */
if (wpa_s->wpa_state != WPA_COMPLETED)
- goto out;
+ return FALSE;
ssid = wpa_s->conf->ssid;
/* At present WPAS P2P_GO mode only applicable for p2p_go */
if (ssid->mode != WPAS_MODE_P2P_GO &&
ssid->mode != WPAS_MODE_AP &&
ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
- goto out;
+ return FALSE;
num_members = p2p_get_group_num_members(wpa_s->p2p_group);
@@ -1604,50 +1636,45 @@ DBusMessage *wpas_dbus_getter_p2p_group_members(DBusMessage * message,
i++;
}
- reply = wpas_dbus_simple_array_property_getter(message,
- DBUS_TYPE_OBJECT_PATH,
- paths, num_members);
+ success = wpas_dbus_simple_array_property_getter(iter,
+ DBUS_TYPE_OBJECT_PATH,
+ paths, num_members,
+ error);
-out_free:
for (i = 0; i < num_members; i++)
os_free(paths[i]);
os_free(paths);
-out:
- return reply;
+ return success;
+
out_of_memory:
- reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
- goto out_free;
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ if (paths) {
+ for (i = 0; i < num_members; i++)
+ os_free(paths[i]);
+ os_free(paths);
+ }
+ return FALSE;
}
-DBusMessage *wpas_dbus_getter_p2p_group_properties(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter, dict_iter;
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, dict_iter;
struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
const struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
int num_vendor_ext = 0;
int i;
if (!hapd) {
- reply = dbus_message_new_error(message, DBUS_ERROR_FAILED,
- NULL);
- return reply;
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "internal error");
+ return FALSE;
}
- if (message == NULL)
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
- else
- reply = dbus_message_new_method_return(message);
-
- if (!reply)
- goto err_no_mem;
-
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
"a{sv}", &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
goto err_no_mem;
@@ -1665,45 +1692,42 @@ DBusMessage *wpas_dbus_getter_p2p_group_properties(
goto err_no_mem;
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(&iter, &variant_iter))
+ !dbus_message_iter_close_container(iter, &variant_iter))
goto err_no_mem;
- return reply;
+ return TRUE;
err_no_mem:
- dbus_message_unref(reply);
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+ return FALSE;
}
-DBusMessage *wpas_dbus_setter_p2p_group_properties(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s)
+
+dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, variant_iter;
- struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING };
- DBusMessageIter iter_dict;
+ struct wpa_supplicant *wpa_s = user_data;
+ DBusMessageIter variant_iter, iter_dict;
+ struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
unsigned int i;
-
struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
- if (!hapd)
- goto error;
-
- dbus_message_iter_init(message, &iter);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_next(&iter);
-
- dbus_message_iter_recurse(&iter, &variant_iter);
+ if (!hapd) {
+ dbus_set_error_const(error, DBUS_ERROR_FAILED,
+ "internal error");
+ return FALSE;
+ }
- if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict))
- return wpas_dbus_error_invalid_args(message, NULL);
+ dbus_message_iter_recurse(iter, &variant_iter);
+ if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
+ return FALSE;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
- reply = wpas_dbus_error_invalid_args(message, NULL);
- break;
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
}
if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) {
@@ -1728,17 +1752,18 @@ DBusMessage *wpas_dbus_setter_p2p_group_properties(
wpa_dbus_dict_entry_clear(&entry);
}
- return reply;
+ return TRUE;
error:
- reply = wpas_dbus_error_invalid_args(message, entry.key);
wpa_dbus_dict_entry_clear(&entry);
-
- return reply;
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
}
-DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
DBusMessage *reply = NULL;
@@ -1753,18 +1778,18 @@ DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error;
if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
- if (!strcmp(entry.key, "service_type") &&
+ if (!os_strcmp(entry.key, "service_type") &&
(entry.type == DBUS_TYPE_STRING)) {
- if (!strcmp(entry.str_value, "upnp"))
+ if (!os_strcmp(entry.str_value, "upnp"))
upnp = 1;
- else if (!strcmp(entry.str_value, "bonjour"))
+ else if (!os_strcmp(entry.str_value, "bonjour"))
bonjour = 1;
else
goto error_clear;
@@ -1777,10 +1802,10 @@ DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message,
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
- if (!strcmp(entry.key, "version") &&
+ if (!os_strcmp(entry.key, "version") &&
entry.type == DBUS_TYPE_INT32)
version = entry.uint32_value;
- else if (!strcmp(entry.key, "service") &&
+ else if (!os_strcmp(entry.key, "service") &&
entry.type == DBUS_TYPE_STRING)
service = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
@@ -1797,13 +1822,14 @@ DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message,
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
- if (!strcmp(entry.key, "query")) {
+ if (!os_strcmp(entry.key, "query")) {
if ((entry.type != DBUS_TYPE_ARRAY) ||
(entry.array_type != DBUS_TYPE_BYTE))
goto error_clear;
- query = wpabuf_alloc_copy(entry.bytearray_value,
- entry.array_len);
- } else if (!strcmp(entry.key, "response")) {
+ query = wpabuf_alloc_copy(
+ entry.bytearray_value,
+ entry.array_len);
+ } else if (!os_strcmp(entry.key, "response")) {
if ((entry.type != DBUS_TYPE_ARRAY) ||
(entry.array_type != DBUS_TYPE_BYTE))
goto error_clear;
@@ -1832,8 +1858,9 @@ error:
return wpas_dbus_error_invalid_args(message, NULL);
}
-DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_delete_service(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
DBusMessage *reply = NULL;
@@ -1848,18 +1875,18 @@ DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error;
if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
- if (!strcmp(entry.key, "service_type") &&
+ if (!os_strcmp(entry.key, "service_type") &&
(entry.type == DBUS_TYPE_STRING)) {
- if (!strcmp(entry.str_value, "upnp"))
+ if (!os_strcmp(entry.str_value, "upnp"))
upnp = 1;
- else if (!strcmp(entry.str_value, "bonjour"))
+ else if (!os_strcmp(entry.str_value, "bonjour"))
bonjour = 1;
else
goto error_clear;
@@ -1870,10 +1897,10 @@ DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message,
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
- if (!strcmp(entry.key, "version") &&
+ if (!os_strcmp(entry.key, "version") &&
entry.type == DBUS_TYPE_INT32)
version = entry.uint32_value;
- else if (!strcmp(entry.key, "service") &&
+ else if (!os_strcmp(entry.key, "service") &&
entry.type == DBUS_TYPE_STRING)
service = os_strdup(entry.str_value);
else
@@ -1894,12 +1921,13 @@ DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message,
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
goto error;
- if (!strcmp(entry.key, "query")) {
+ if (!os_strcmp(entry.key, "query")) {
if ((entry.type != DBUS_TYPE_ARRAY) ||
(entry.array_type != DBUS_TYPE_BYTE))
goto error_clear;
- query = wpabuf_alloc_copy(entry.bytearray_value,
- entry.array_len);
+ query = wpabuf_alloc_copy(
+ entry.bytearray_value,
+ entry.array_len);
} else
goto error_clear;
@@ -1923,15 +1951,17 @@ error:
return wpas_dbus_error_invalid_args(message, NULL);
}
-DBusMessage *wpas_dbus_handler_p2p_flush_service(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_flush_service(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
{
wpas_p2p_service_flush(wpa_s);
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_service_sd_req(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
DBusMessage *reply = NULL;
@@ -1947,28 +1977,28 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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, "peer_object") &&
+ if (!os_strcmp(entry.key, "peer_object") &&
entry.type == DBUS_TYPE_OBJECT_PATH) {
peer_object_path = os_strdup(entry.str_value);
- } else if (!strcmp(entry.key, "service_type") &&
+ } else if (!os_strcmp(entry.key, "service_type") &&
entry.type == DBUS_TYPE_STRING) {
- if (!strcmp(entry.str_value, "upnp"))
+ if (!os_strcmp(entry.str_value, "upnp"))
upnp = 1;
else
goto error_clear;
- } else if (!strcmp(entry.key, "version") &&
+ } else if (!os_strcmp(entry.key, "version") &&
entry.type == DBUS_TYPE_INT32) {
version = entry.uint32_value;
- } else if (!strcmp(entry.key, "service") &&
+ } else if (!os_strcmp(entry.key, "service") &&
entry.type == DBUS_TYPE_STRING) {
service = os_strdup(entry.str_value);
- } else if (!strcmp(entry.key, "tlv")) {
+ } else if (!os_strcmp(entry.key, "tlv")) {
if (entry.type != DBUS_TYPE_ARRAY ||
entry.array_type != DBUS_TYPE_BYTE)
goto error_clear;
@@ -1982,19 +2012,18 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message,
if (!peer_object_path ||
(parse_peer_object_path(peer_object_path, addr) < 0) ||
- (p2p_get_peer_info(wpa_s->global->p2p, addr, 0, NULL, 0) < 0))
+ !p2p_peer_known(wpa_s->global->p2p, addr))
goto error;
if (upnp == 1) {
if (version <= 0 || service == NULL)
goto error;
- ref = (unsigned long)wpas_p2p_sd_request_upnp(wpa_s, addr,
- version, service);
+ ref = wpas_p2p_sd_request_upnp(wpa_s, addr, version, service);
} else {
if (tlv == NULL)
goto error;
- ref = (unsigned long)wpas_p2p_sd_request(wpa_s, addr, tlv);
+ ref = wpas_p2p_sd_request(wpa_s, addr, tlv);
wpabuf_free(tlv);
}
@@ -2003,8 +2032,8 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message,
dbus_message_append_args(reply, DBUS_TYPE_UINT64,
&ref, DBUS_TYPE_INVALID);
} else {
- reply = wpas_dbus_error_unknown_error(message,
- "Unable to send SD request");
+ reply = wpas_dbus_error_unknown_error(
+ message, "Unable to send SD request");
}
out:
os_free(service);
@@ -2019,7 +2048,8 @@ error:
goto out;
}
-DBusMessage *wpas_dbus_handler_p2p_service_sd_res(
+
+DBusMessage * wpas_dbus_handler_p2p_service_sd_res(
DBusMessage *message, struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter_dict;
@@ -2034,23 +2064,23 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_res(
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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, "peer_object") &&
+ if (!os_strcmp(entry.key, "peer_object") &&
entry.type == DBUS_TYPE_OBJECT_PATH) {
peer_object_path = os_strdup(entry.str_value);
- } else if (!strcmp(entry.key, "frequency") &&
+ } else if (!os_strcmp(entry.key, "frequency") &&
entry.type == DBUS_TYPE_INT32) {
freq = entry.uint32_value;
- } else if (!strcmp(entry.key, "dialog_token") &&
+ } else if (!os_strcmp(entry.key, "dialog_token") &&
entry.type == DBUS_TYPE_UINT32) {
dlg_tok = entry.uint32_value;
- } else if (!strcmp(entry.key, "tlvs")) {
+ } else if (!os_strcmp(entry.key, "tlvs")) {
if (entry.type != DBUS_TYPE_ARRAY ||
entry.array_type != DBUS_TYPE_BYTE)
goto error_clear;
@@ -2063,7 +2093,7 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_res(
}
if (!peer_object_path ||
(parse_peer_object_path(peer_object_path, addr) < 0) ||
- (p2p_get_peer_info(wpa_s->global->p2p, addr, 0, NULL, 0) < 0))
+ !p2p_peer_known(wpa_s->global->p2p, addr))
goto error;
if (tlv == NULL)
@@ -2081,8 +2111,9 @@ error:
goto out;
}
-DBusMessage *wpas_dbus_handler_p2p_service_sd_cancel_req(DBusMessage * message, struct wpa_supplicant
- *wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_service_sd_cancel_req(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter;
u64 req = 0;
@@ -2093,7 +2124,7 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_cancel_req(DBusMessage * message,
if (req == 0)
goto error;
- if (!wpas_p2p_sd_cancel_request(wpa_s, (void *)(unsigned long)req))
+ if (!wpas_p2p_sd_cancel_request(wpa_s, req))
goto error;
return NULL;
@@ -2101,16 +2132,17 @@ error:
return wpas_dbus_error_invalid_args(message, NULL);
}
-DBusMessage *wpas_dbus_handler_p2p_service_update(DBusMessage * message,
- struct wpa_supplicant * wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_service_update(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
wpas_p2p_sd_service_update(wpa_s);
return NULL;
}
-DBusMessage *wpas_dbus_handler_p2p_serv_disc_external(DBusMessage * message,
- struct wpa_supplicant *
- wpa_s)
+
+DBusMessage * wpas_dbus_handler_p2p_serv_disc_external(
+ DBusMessage *message, struct wpa_supplicant *wpa_s)
{
DBusMessageIter iter;
int ext = 0;
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
index ed9a345..206e904 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
@@ -94,61 +94,69 @@ DBusMessage *wpas_dbus_handler_p2p_serv_disc_external(
/*
* P2P Device property accessor methods.
*/
-DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_group(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_peergo(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
/*
* P2P Peer properties.
*/
-DBusMessage *wpas_dbus_getter_p2p_peer_properties(
- DBusMessage *message,
- struct peer_handler_args *peer);
+dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_peer_ies(
- DBusMessage *message,
- struct peer_handler_args *peer);
+dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
/*
* P2P Group properties
*/
-DBusMessage *wpas_dbus_getter_p2p_group_members(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_getter_p2p_group_properties(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
-DBusMessage *wpas_dbus_setter_p2p_group_properties(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s);
+dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
/*
* P2P Persistent Groups and properties
*/
-DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_getter_persistent_group_properties(
- DBusMessage *message, struct network_handler_args *net);
-DBusMessage * wpas_dbus_setter_persistent_group_properties(
- DBusMessage *message, struct network_handler_args *net);
+dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
+
+dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter,
+ DBusError *error, void *user_data);
+
+dbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
+
DBusMessage * wpas_dbus_handler_add_persistent_group(
DBusMessage *message, struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index c118d73..a72cfb3 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -19,6 +19,8 @@
#include "../config.h"
#include "../wpa_supplicant_i.h"
#include "../wps_supplicant.h"
+#include "../driver_i.h"
+#include "../ap.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
@@ -30,6 +32,7 @@ struct wps_start_params {
int type; /* 0 - not set, 1 - pin, 2 - pbc */
u8 *bssid;
char *pin;
+ u8 *p2p_dev_addr;
};
@@ -148,6 +151,41 @@ static int wpas_dbus_handler_wps_pin(DBusMessage *message,
}
+#ifdef CONFIG_P2P
+static int wpas_dbus_handler_wps_p2p_dev_addr(DBusMessage *message,
+ DBusMessageIter *entry_iter,
+ struct wps_start_params *params,
+ DBusMessage **reply)
+{
+ DBusMessageIter variant_iter, array_iter;
+ int len;
+
+ dbus_message_iter_recurse(entry_iter, &variant_iter);
+ if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&variant_iter) !=
+ DBUS_TYPE_BYTE) {
+ wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong "
+ "P2PDeviceAddress type, byte array required");
+ *reply = wpas_dbus_error_invalid_args(
+ message, "P2PDeviceAddress must be a byte array");
+ return -1;
+ }
+ dbus_message_iter_recurse(&variant_iter, &array_iter);
+ dbus_message_iter_get_fixed_array(&array_iter, &params->p2p_dev_addr,
+ &len);
+ if (len != ETH_ALEN) {
+ wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong "
+ "P2PDeviceAddress length %d", len);
+ *reply = wpas_dbus_error_invalid_args(message,
+ "P2PDeviceAddress "
+ "has wrong length");
+ return -1;
+ }
+ return 0;
+}
+#endif /* CONFIG_P2P */
+
+
static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
DBusMessageIter *entry_iter,
struct wps_start_params *params,
@@ -165,6 +203,11 @@ static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
else if (os_strcmp(key, "Pin") == 0)
return wpas_dbus_handler_wps_pin(message, entry_iter,
params, reply);
+#ifdef CONFIG_P2P
+ else if (os_strcmp(key, "P2PDeviceAddress") == 0)
+ return wpas_dbus_handler_wps_p2p_dev_addr(message, entry_iter,
+ params, reply);
+#endif /* CONFIG_P2P */
wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key);
*reply = wpas_dbus_error_invalid_args(message, key);
@@ -231,12 +274,31 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin,
NULL);
else if (params.type == 1) {
- ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0,
- DEV_PW_DEFAULT);
- if (ret > 0)
- os_snprintf(npin, sizeof(npin), "%08d", ret);
- } else
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface)
+ ret = wpa_supplicant_ap_wps_pin(wpa_s,
+ params.bssid,
+ params.pin,
+ npin, sizeof(npin));
+ else
+#endif /* CONFIG_AP */
+ {
+ ret = wpas_wps_start_pin(wpa_s, params.bssid,
+ params.pin, 0,
+ DEV_PW_DEFAULT);
+ if (ret > 0)
+ os_snprintf(npin, sizeof(npin), "%08d", ret);
+ }
+ } else {
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface)
+ ret = wpa_supplicant_ap_wps_pbc(wpa_s,
+ params.bssid,
+ params.p2p_dev_addr);
+ else
+#endif /* CONFIG_AP */
ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
+ }
if (ret < 0) {
wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in "
@@ -284,40 +346,43 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
* wpas_dbus_getter_process_credentials - Check if credentials are processed
* @message: Pointer to incoming dbus message
* @wpa_s: %wpa_supplicant data structure
- * Returns: DBus message with a boolean on success or DBus error on failure
+ * Returns: TRUE on success, FALSE on failure
*
* Getter for "ProcessCredentials" property. Returns returned boolean will be
* true if wps_cred_processing configuration field is not equal to 1 or false
* if otherwise.
*/
-DBusMessage * wpas_dbus_getter_process_credentials(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
+ struct wpa_supplicant *wpa_s = user_data;
dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
- return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
- &process);
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+ &process, error);
}
/**
* wpas_dbus_setter_process_credentials - Set credentials_processed conf param
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: NULL on success or DBus error on failure
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
*
* Setter for "ProcessCredentials" property. Sets credentials_processed on 2
* if boolean argument is true or on 1 if otherwise.
*/
-DBusMessage * wpas_dbus_setter_process_credentials(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
+dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data)
{
- DBusMessage *reply = NULL;
+ struct wpa_supplicant *wpa_s = user_data;
dbus_bool_t process_credentials, old_pc;
- reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
- &process_credentials);
- if (reply)
- return reply;
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+ &process_credentials))
+ return FALSE;
old_pc = (wpa_s->conf->wps_cred_processing != 1);
wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
@@ -328,5 +393,5 @@ DBusMessage * wpas_dbus_setter_process_credentials(
WPAS_DBUS_NEW_IFACE_WPS,
"ProcessCredentials");
- return NULL;
+ return TRUE;
}
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
index 78611d4..e254365 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ b/wpa_supplicant/dbus/dbus_new_helpers.c
@@ -21,112 +21,50 @@
#include "dbus_common_i.h"
#include "dbus_new.h"
#include "dbus_new_helpers.h"
+#include "dbus_dict_helpers.h"
-/**
- * recursive_iter_copy - Reads arguments from one iterator and
- * writes to another recursively
- * @from: iterator to read from
- * @to: iterator to write to
- *
- * Copies one iterator's elements to another. If any element in
- * iterator is of container type, its content is copied recursively
- */
-static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to)
+static dbus_bool_t fill_dict_with_properties(
+ DBusMessageIter *dict_iter,
+ const struct wpa_dbus_property_desc *props,
+ const char *interface, void *user_data, DBusError *error)
{
-
- char *subtype = NULL;
- int type;
-
- /* iterate over iterator to copy */
- while ((type = dbus_message_iter_get_arg_type(from)) !=
- DBUS_TYPE_INVALID) {
-
- /* simply copy basic type entries */
- if (dbus_type_is_basic(type)) {
- if (dbus_type_is_fixed(type)) {
- /*
- * According to DBus documentation all
- * fixed-length types are guaranteed to fit
- * 8 bytes
- */
- dbus_uint64_t v;
- dbus_message_iter_get_basic(from, &v);
- dbus_message_iter_append_basic(to, type, &v);
- } else {
- char *v;
- dbus_message_iter_get_basic(from, &v);
- dbus_message_iter_append_basic(to, type, &v);
- }
- } else {
- /* recursively copy container type entries */
- DBusMessageIter write_subiter, read_subiter;
-
- dbus_message_iter_recurse(from, &read_subiter);
-
- if (type == DBUS_TYPE_VARIANT ||
- type == DBUS_TYPE_ARRAY) {
- subtype = dbus_message_iter_get_signature(
- &read_subiter);
- }
-
- dbus_message_iter_open_container(to, type, subtype,
- &write_subiter);
-
- recursive_iter_copy(&read_subiter, &write_subiter);
-
- dbus_message_iter_close_container(to, &write_subiter);
- if (subtype)
- dbus_free(subtype);
- }
-
- dbus_message_iter_next(from);
- }
-}
-
-
-static unsigned int fill_dict_with_properties(
- DBusMessageIter *dict_iter, const struct wpa_dbus_property_desc *props,
- const char *interface, const void *user_data)
-{
- DBusMessage *reply;
- DBusMessageIter entry_iter, ret_iter;
- unsigned int counter = 0;
+ DBusMessageIter entry_iter;
const struct wpa_dbus_property_desc *dsc;
for (dsc = props; dsc && dsc->dbus_property; dsc++) {
- if (!os_strncmp(dsc->dbus_interface, interface,
- WPAS_DBUS_INTERFACE_MAX) &&
- dsc->access != W && dsc->getter) {
- reply = dsc->getter(NULL, user_data);
- if (!reply)
- continue;
-
- if (dbus_message_get_type(reply) ==
- DBUS_MESSAGE_TYPE_ERROR) {
- dbus_message_unref(reply);
- continue;
- }
+ /* Only return properties for the requested D-Bus interface */
+ if (os_strncmp(dsc->dbus_interface, interface,
+ WPAS_DBUS_INTERFACE_MAX) != 0)
+ continue;
- dbus_message_iter_init(reply, &ret_iter);
+ /* Skip write-only properties */
+ if (dsc->getter == NULL)
+ continue;
- dbus_message_iter_open_container(dict_iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter);
- dbus_message_iter_append_basic(
- &entry_iter, DBUS_TYPE_STRING,
- &dsc->dbus_property);
+ if (!dbus_message_iter_open_container(dict_iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry_iter)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
+ return FALSE;
+ }
+ if (!dbus_message_iter_append_basic(&entry_iter,
+ DBUS_TYPE_STRING,
+ &dsc->dbus_property)) {
+ dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
+ "no memory");
+ return FALSE;
+ }
- recursive_iter_copy(&ret_iter, &entry_iter);
+ /* An error getting a property fails the request entirely */
+ if (!dsc->getter(&entry_iter, error, user_data))
+ return FALSE;
- dbus_message_iter_close_container(dict_iter,
- &entry_iter);
- dbus_message_unref(reply);
- counter++;
- }
+ dbus_message_iter_close_container(dict_iter, &entry_iter);
}
- return counter;
+ return TRUE;
}
@@ -142,37 +80,44 @@ static unsigned int fill_dict_with_properties(
* specified as argument. Returned message contains one dict argument
* with properties names as keys and theirs values as values.
*/
-static DBusMessage * get_all_properties(
- DBusMessage *message, char *interface,
- struct wpa_dbus_object_desc *obj_dsc)
+static DBusMessage * get_all_properties(DBusMessage *message, char *interface,
+ struct wpa_dbus_object_desc *obj_dsc)
{
- /* Create and initialize the return message */
- DBusMessage *reply = dbus_message_new_method_return(message);
+ DBusMessage *reply;
DBusMessageIter iter, dict_iter;
- int props_num;
-
- dbus_message_iter_init_append(reply, &iter);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &dict_iter);
+ DBusError error;
- props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties,
- interface, obj_dsc->user_data);
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL) {
+ wpa_printf(MSG_ERROR, "%s: out of memory creating dbus reply",
+ __func__);
+ return NULL;
+ }
- dbus_message_iter_close_container(&iter, &dict_iter);
+ dbus_message_iter_init_append(reply, &iter);
+ if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
+ wpa_printf(MSG_ERROR, "%s: out of memory creating reply",
+ __func__);
+ dbus_message_unref(reply);
+ reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
+ "out of memory");
+ return reply;
+ }
- if (props_num == 0) {
+ dbus_error_init(&error);
+ if (!fill_dict_with_properties(&dict_iter, obj_dsc->properties,
+ interface, obj_dsc->user_data, &error))
+ {
dbus_message_unref(reply);
- reply = dbus_message_new_error(message,
- DBUS_ERROR_INVALID_ARGS,
- "No readable properties in "
- "this interface");
+ reply = wpas_dbus_reply_new_from_error(message, &error,
+ DBUS_ERROR_INVALID_ARGS,
+ "No readable properties"
+ " in this interface");
+ dbus_error_free(&error);
+ return reply;
}
+ wpa_dbus_dict_close_write(&iter, &dict_iter);
return reply;
}
@@ -219,15 +164,33 @@ static DBusMessage * properties_get(DBusMessage *message,
const struct wpa_dbus_property_desc *dsc,
void *user_data)
{
- if (os_strcmp(dbus_message_get_signature(message), "ss"))
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+
+ if (os_strcmp(dbus_message_get_signature(message), "ss")) {
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
NULL);
+ }
- if (dsc->access != W && dsc->getter)
- return dsc->getter(message, user_data);
+ if (dsc->getter == NULL) {
+ return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+ "Property is write-only");
+ }
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_iter_init_append(reply, &iter);
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Property is write-only");
+ dbus_error_init(&error);
+ if (dsc->getter(&iter, &error, user_data) == FALSE) {
+ dbus_message_unref(reply);
+ reply = wpas_dbus_reply_new_from_error(
+ message, &error, DBUS_ERROR_FAILED,
+ "Failed to read property");
+ dbus_error_free(&error);
+ }
+
+ return reply;
}
@@ -235,15 +198,38 @@ static DBusMessage * properties_set(DBusMessage *message,
const struct wpa_dbus_property_desc *dsc,
void *user_data)
{
- if (os_strcmp(dbus_message_get_signature(message), "ssv"))
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+
+ if (os_strcmp(dbus_message_get_signature(message), "ssv")) {
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
NULL);
+ }
+
+ if (dsc->setter == NULL) {
+ return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
+ "Property is read-only");
+ }
+
+ dbus_message_iter_init(message, &iter);
+ /* Skip the interface name and the property name */
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_next(&iter);
- if (dsc->access != R && dsc->setter)
- return dsc->setter(message, user_data);
+ /* Iter will now point to the property's new value */
+ dbus_error_init(&error);
+ if (dsc->setter(&iter, &error, user_data) == TRUE) {
+ /* Success */
+ reply = dbus_message_new_method_return(message);
+ } else {
+ reply = wpas_dbus_reply_new_from_error(
+ message, &error, DBUS_ERROR_FAILED,
+ "Failed to set property");
+ dbus_error_free(&error);
+ }
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Property is read-only");
+ return reply;
}
@@ -622,14 +608,14 @@ int wpa_dbus_unregister_object_per_iface(
}
-static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc,
- const char *interface,
- DBusMessageIter *dict_iter)
+static dbus_bool_t put_changed_properties(
+ const struct wpa_dbus_object_desc *obj_dsc, const char *interface,
+ DBusMessageIter *dict_iter, int clear_changed)
{
- DBusMessage *getter_reply;
- DBusMessageIter prop_iter, entry_iter;
+ DBusMessageIter entry_iter;
const struct wpa_dbus_property_desc *dsc;
int i;
+ DBusError error;
for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property;
dsc++, i++) {
@@ -638,43 +624,94 @@ static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc,
continue;
if (os_strcmp(dsc->dbus_interface, interface) != 0)
continue;
- obj_dsc->prop_changed_flags[i] = 0;
-
- getter_reply = dsc->getter(NULL, obj_dsc->user_data);
- if (!getter_reply ||
- dbus_message_get_type(getter_reply) ==
- DBUS_MESSAGE_TYPE_ERROR) {
- wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new value "
- "of property %s", __func__,
- dsc->dbus_property);
- continue;
- }
+ if (clear_changed)
+ obj_dsc->prop_changed_flags[i] = 0;
- if (!dbus_message_iter_init(getter_reply, &prop_iter) ||
- !dbus_message_iter_open_container(dict_iter,
+ if (!dbus_message_iter_open_container(dict_iter,
DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter) ||
- !dbus_message_iter_append_basic(&entry_iter,
+ NULL, &entry_iter))
+ return FALSE;
+
+ if (!dbus_message_iter_append_basic(&entry_iter,
DBUS_TYPE_STRING,
&dsc->dbus_property))
- goto err;
-
- recursive_iter_copy(&prop_iter, &entry_iter);
+ return FALSE;
+
+ dbus_error_init(&error);
+ if (!dsc->getter(&entry_iter, &error, obj_dsc->user_data)) {
+ if (dbus_error_is_set (&error)) {
+ wpa_printf(MSG_ERROR, "dbus: %s: Cannot get "
+ "new value of property %s: (%s) %s",
+ __func__, dsc->dbus_property,
+ error.name, error.message);
+ } else {
+ wpa_printf(MSG_ERROR, "dbus: %s: Cannot get "
+ "new value of property %s",
+ __func__, dsc->dbus_property);
+ }
+ dbus_error_free(&error);
+ return FALSE;
+ }
if (!dbus_message_iter_close_container(dict_iter, &entry_iter))
- goto err;
-
- dbus_message_unref(getter_reply);
+ return FALSE;
}
+ return TRUE;
+}
+
+
+static void do_send_prop_changed_signal(
+ DBusConnection *con, const char *path, const char *interface,
+ const struct wpa_dbus_object_desc *obj_dsc)
+{
+ DBusMessage *msg;
+ DBusMessageIter signal_iter, dict_iter;
+
+ msg = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
+ "PropertiesChanged");
+ if (msg == NULL)
+ return;
+
+ dbus_message_iter_init_append(msg, &signal_iter);
+
+ if (!dbus_message_iter_append_basic(&signal_iter, DBUS_TYPE_STRING,
+ &interface))
+ goto err;
+
+ /* Changed properties dict */
+ if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
+ "{sv}", &dict_iter))
+ goto err;
+
+ if (!put_changed_properties(obj_dsc, interface, &dict_iter, 0))
+ goto err;
+
+ if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
+ goto err;
+
+ /* Invalidated properties array (empty) */
+ if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
+ "s", &dict_iter))
+ goto err;
+
+ if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
+ goto err;
+
+ dbus_connection_send(con, msg, NULL);
+
+out:
+ dbus_message_unref(msg);
return;
err:
- wpa_printf(MSG_ERROR, "dbus: %s: Cannot construct signal", __func__);
+ wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal",
+ __func__);
+ goto out;
}
-static void send_prop_changed_signal(
+static void do_send_deprecated_prop_changed_signal(
DBusConnection *con, const char *path, const char *interface,
const struct wpa_dbus_object_desc *obj_dsc)
{
@@ -691,7 +728,8 @@ static void send_prop_changed_signal(
"{sv}", &dict_iter))
goto err;
- put_changed_properties(obj_dsc, interface, &dict_iter);
+ if (!put_changed_properties(obj_dsc, interface, &dict_iter, 1))
+ goto err;
if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
goto err;
@@ -709,6 +747,29 @@ err:
}
+static void send_prop_changed_signal(
+ DBusConnection *con, const char *path, const char *interface,
+ const struct wpa_dbus_object_desc *obj_dsc)
+{
+ /*
+ * First, send property change notification on the standardized
+ * org.freedesktop.DBus.Properties interface. This call will not
+ * clear the property change bits, so that they are preserved for
+ * the call that follows.
+ */
+ do_send_prop_changed_signal(con, path, interface, obj_dsc);
+
+ /*
+ * Now send PropertiesChanged on our own interface for backwards
+ * compatibility. This is deprecated and will be removed in a future
+ * release.
+ */
+ do_send_deprecated_prop_changed_signal(con, path, interface, obj_dsc);
+
+ /* Property change bits have now been cleared. */
+}
+
+
static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx)
{
DBusConnection *con = eloop_ctx;
@@ -860,29 +921,49 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
* @iface: dbus priv struct
* @path: path to DBus object which properties will be obtained
* @interface: interface name which properties will be obtained
- * @dict_iter: correct, open DBus dictionary iterator.
+ * @iter: DBus message iter at which to append property dictionary.
*
* Iterates over all properties registered with object and execute getters
* of those, which are readable and which interface matches interface
* specified as argument. Obtained properties values are stored in
* dict_iter dictionary.
*/
-void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
- const char *path, const char *interface,
- DBusMessageIter *dict_iter)
+dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
+ const char *path,
+ const char *interface,
+ DBusMessageIter *iter)
{
struct wpa_dbus_object_desc *obj_desc = NULL;
+ DBusMessageIter dict_iter;
+ DBusError error;
dbus_connection_get_object_path_data(iface->con, path,
(void **) &obj_desc);
if (!obj_desc) {
- wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: "
- "could not obtain object's private data: %s", path);
- return;
+ wpa_printf(MSG_ERROR, "dbus: %s: could not obtain object's "
+ "private data: %s", __func__, path);
+ return FALSE;
+ }
+
+ if (!wpa_dbus_dict_open_write(iter, &dict_iter)) {
+ wpa_printf(MSG_ERROR, "dbus: %s: failed to open message dict",
+ __func__);
+ return FALSE;
+ }
+
+ dbus_error_init(&error);
+ if (!fill_dict_with_properties(&dict_iter, obj_desc->properties,
+ interface, obj_desc->user_data,
+ &error)) {
+ wpa_printf(MSG_ERROR, "dbus: %s: failed to get object"
+ " properties: (%s) %s", __func__,
+ dbus_error_is_set(&error) ? error.name : "none",
+ dbus_error_is_set(&error) ? error.message : "none");
+ dbus_error_free(&error);
+ return FALSE;
}
- fill_dict_with_properties(dict_iter, obj_desc->properties,
- interface, obj_desc->user_data);
+ return wpa_dbus_dict_close_write(iter, &dict_iter);
}
/**
@@ -955,3 +1036,32 @@ char *wpas_dbus_new_decompose_object_path(const char *path,
return obj_path_only;
}
+
+
+/**
+ * wpas_dbus_reply_new_from_error - Create a new D-Bus error message from a
+ * dbus error structure
+ * @message: The original request message for which the error is a reply
+ * @error: The error containing a name and a descriptive error cause
+ * @fallback_name: A generic error name if @error was not set
+ * @fallback_string: A generic error string if @error was not set
+ * Returns: A new D-Bus error message
+ *
+ * Given a DBusMessage structure, creates a new D-Bus error message using
+ * the error name and string contained in that structure.
+ */
+DBusMessage * wpas_dbus_reply_new_from_error(DBusMessage *message,
+ DBusError *error,
+ const char *fallback_name,
+ const char *fallback_string)
+{
+ if (error && error->name && error->message) {
+ return dbus_message_new_error(message, error->name,
+ error->message);
+ }
+ if (fallback_name && fallback_string) {
+ return dbus_message_new_error(message, fallback_name,
+ fallback_string);
+ }
+ return NULL;
+}
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index fd21c22..d6e7b48 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -22,8 +22,9 @@ typedef DBusMessage * (* WPADBusMethodHandler)(DBusMessage *message,
void *user_data);
typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg);
-typedef DBusMessage * (* WPADBusPropertyAccessor)(DBusMessage *message,
- const void *user_data);
+typedef dbus_bool_t (* WPADBusPropertyAccessor)(DBusMessageIter *iter,
+ DBusError *error,
+ void *user_data);
struct wpa_dbus_object_desc {
DBusConnection *connection;
@@ -44,8 +45,6 @@ struct wpa_dbus_object_desc {
WPADBusArgumentFreeFunction user_data_free_func;
};
-enum dbus_prop_access { R, W, RW };
-
enum dbus_arg_direction { ARG_IN, ARG_OUT };
struct wpa_dbus_argument {
@@ -67,7 +66,7 @@ struct wpa_dbus_method_desc {
/* method handling function */
WPADBusMethodHandler method_handler;
/* array of arguments */
- struct wpa_dbus_argument args[3];
+ struct wpa_dbus_argument args[4];
};
/**
@@ -79,7 +78,7 @@ struct wpa_dbus_signal_desc {
/* signal interface */
const char *dbus_interface;
/* array of arguments */
- struct wpa_dbus_argument args[3];
+ struct wpa_dbus_argument args[4];
};
/**
@@ -96,8 +95,6 @@ struct wpa_dbus_property_desc {
WPADBusPropertyAccessor getter;
/* property setter function */
WPADBusPropertyAccessor setter;
- /* property access permissions */
- enum dbus_prop_access access;
};
@@ -128,9 +125,10 @@ int wpa_dbus_unregister_object_per_iface(
struct wpas_dbus_priv *ctrl_iface,
const char *path);
-void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
- const char *path, const char *interface,
- DBusMessageIter *dict_iter);
+dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
+ const char *path,
+ const char *interface,
+ DBusMessageIter *iter);
void wpa_dbus_flush_all_changed_properties(DBusConnection *con);
@@ -150,4 +148,9 @@ char *wpas_dbus_new_decompose_object_path(const char *path,
char **network,
char **bssid);
+DBusMessage *wpas_dbus_reply_new_from_error(DBusMessage *message,
+ DBusError *error,
+ const char *fallback_name,
+ const char *fallback_string);
+
#endif /* WPA_DBUS_CTRL_H */
diff --git a/wpa_supplicant/dbus/dbus_new_introspect.c b/wpa_supplicant/dbus/dbus_new_introspect.c
index fd433df..fb29f20 100644
--- a/wpa_supplicant/dbus/dbus_new_introspect.c
+++ b/wpa_supplicant/dbus/dbus_new_introspect.c
@@ -89,10 +89,11 @@ static void add_entry(struct wpabuf *xml, const char *type, const char *name,
static void add_property(struct wpabuf *xml,
const struct wpa_dbus_property_desc *dsc)
{
- wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" access=\"%s\"/>",
+ wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" "
+ "access=\"%s%s\"/>",
dsc->dbus_property, dsc->type,
- (dsc->access == R ? "read" :
- (dsc->access == W ? "write" : "readwrite")));
+ dsc->getter ? "read" : "",
+ dsc->setter ? "write" : "");
}
diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
index d255e14..71ab61e 100644
--- a/wpa_supplicant/dbus/dbus_old.c
+++ b/wpa_supplicant/dbus/dbus_old.c
@@ -23,7 +23,6 @@
#include "../bss.h"
#include "dbus_old.h"
#include "dbus_old_handlers.h"
-#include "dbus_common.h"
#include "dbus_common_i.h"
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
index 39fe241..a7eabf3 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers.c
@@ -116,7 +116,7 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
DBusMessageIter iter_dict;
struct wpa_dbus_dict_entry entry;
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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))
@@ -229,7 +229,7 @@ DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
goto out;
}
- if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) {
+ if (!wpa_supplicant_remove_iface(global, wpa_s)) {
reply = wpas_dbus_new_success_reply(message);
} else {
reply = dbus_message_new_error(message,
@@ -922,7 +922,7 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) {
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
reply = wpas_dbus_new_invalid_opts_error(message, NULL);
goto out;
}
@@ -1202,7 +1202,7 @@ DBusMessage * wpas_dbus_iface_set_smartcard_modules(
if (!dbus_message_iter_init(message, &iter))
goto error;
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@@ -1324,7 +1324,7 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
dbus_message_iter_init(message, &iter);
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ 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)) {
diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service
deleted file mode 100644
index a9ce1ec..0000000
--- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=fi.epitest.hostap.WPASupplicant
-Exec=/sbin/wpa_supplicant -u
-User=root
diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service
deleted file mode 100644
index df78471..0000000
--- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=fi.w1.wpa_supplicant1
-Exec=/sbin/wpa_supplicant -u
-User=root
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index 429ff3b..cff25d6 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -114,11 +114,6 @@ CONFIG_DRIVER_NL80211=y
# Driver interface for development testing
#CONFIG_DRIVER_TEST=y
-# Include client MLME (management frame processing) for test driver
-# This can be used to test MLME operations in hostapd with the test interface.
-# space.
-#CONFIG_CLIENT_MLME=y
-
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
@@ -203,6 +198,9 @@ CONFIG_EAP_LEAP=y
#CONFIG_WPS2=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
+# Disable credentials for an open network by default when acting as a WPS
+# registrar.
+#CONFIG_WPS_REG_DISABLE_OPEN=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
@@ -322,18 +320,24 @@ CONFIG_PEERKEY=y
# Select TLS implementation
# openssl = OpenSSL (default)
-# gnutls = GnuTLS (needed for TLS/IA, see also CONFIG_GNUTLS_EXTRA)
+# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# none = Empty template
#CONFIG_TLS=openssl
-# Whether to enable TLS/IA support, which is required for EAP-TTLSv1.
-# You need CONFIG_TLS=gnutls for this to have any effect. Please note that
-# even though the core GnuTLS library is released under LGPL, this extra
-# library uses GPL and as such, the terms of GPL apply to the combination
-# of wpa_supplicant and GnuTLS if this option is enabled. BSD license may not
-# apply for distribution of the resulting binary.
-#CONFIG_GNUTLS_EXTRA=y
+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
+# can be enabled to get a stronger construction of messages when block ciphers
+# are used. It should be noted that some existing TLS v1.0 -based
+# implementation may not be compatible with TLS v1.1 message (ClientHello is
+# sent prior to negotiating which version will be used)
+#CONFIG_TLSV11=y
+
+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
+# can be enabled to enable use of stronger crypto algorithms. It should be
+# noted that some existing TLS v1.0 -based implementation may not be compatible
+# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
+# will be used)
+#CONFIG_TLSV12=y
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
@@ -455,3 +459,12 @@ CONFIG_PEERKEY=y
# should only be considered for builds that are known to be used on devices
# that meet the requirements described above.
#CONFIG_NO_RANDOM_POOL=y
+
+# IEEE 802.11n (High Throughput) support (mainly for AP mode)
+#CONFIG_IEEE80211N=y
+
+# Interworking (IEEE 802.11u)
+# 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
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index b0c5ef0..108599f 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -79,6 +79,23 @@ static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s,
return -1;
}
+static inline int wpa_drv_sched_scan(struct wpa_supplicant *wpa_s,
+ struct wpa_driver_scan_params *params,
+ u32 interval)
+{
+ if (wpa_s->driver->sched_scan)
+ return wpa_s->driver->sched_scan(wpa_s->drv_priv,
+ params, interval);
+ return -1;
+}
+
+static inline int wpa_drv_stop_sched_scan(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->driver->stop_sched_scan)
+ return wpa_s->driver->stop_sched_scan(wpa_s->drv_priv);
+ return -1;
+}
+
static inline struct wpa_scan_results * wpa_drv_get_scan_results2(
struct wpa_supplicant *wpa_s)
{
@@ -236,35 +253,6 @@ wpa_drv_get_hw_feature_data(struct wpa_supplicant *wpa_s, u16 *num_modes,
return NULL;
}
-static inline int wpa_drv_set_channel(struct wpa_supplicant *wpa_s,
- enum hostapd_hw_mode phymode, int chan,
- int freq)
-{
- if (wpa_s->driver->set_channel)
- return wpa_s->driver->set_channel(wpa_s->drv_priv, phymode,
- chan, freq);
- return -1;
-}
-
-static inline int wpa_drv_set_ssid(struct wpa_supplicant *wpa_s,
- const u8 *ssid, size_t ssid_len)
-{
- if (wpa_s->driver->set_ssid) {
- return wpa_s->driver->set_ssid(wpa_s->drv_priv, ssid,
- ssid_len);
- }
- return -1;
-}
-
-static inline int wpa_drv_set_bssid(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- if (wpa_s->driver->set_bssid) {
- return wpa_s->driver->set_bssid(wpa_s->drv_priv, bssid);
- }
- return -1;
-}
-
static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s,
const char *alpha2)
{
@@ -274,29 +262,11 @@ static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s,
}
static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t data_len)
+ const u8 *data, size_t data_len, int noack)
{
if (wpa_s->driver->send_mlme)
return wpa_s->driver->send_mlme(wpa_s->drv_priv,
- data, data_len);
- return -1;
-}
-
-static inline int wpa_drv_mlme_add_sta(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *supp_rates,
- size_t supp_rates_len)
-{
- if (wpa_s->driver->mlme_add_sta)
- return wpa_s->driver->mlme_add_sta(wpa_s->drv_priv, addr,
- supp_rates, supp_rates_len);
- return -1;
-}
-
-static inline int wpa_drv_mlme_remove_sta(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- if (wpa_s->driver->mlme_remove_sta)
- return wpa_s->driver->mlme_remove_sta(wpa_s->drv_priv, addr);
+ data, data_len, noack);
return -1;
}
@@ -320,15 +290,11 @@ static inline int wpa_drv_send_ft_action(struct wpa_supplicant *wpa_s,
return -1;
}
-static inline int wpa_drv_set_beacon(struct wpa_supplicant *wpa_s,
- const u8 *head, size_t head_len,
- const u8 *tail, size_t tail_len,
- int dtim_period, int beacon_int)
+static inline int wpa_drv_set_ap(struct wpa_supplicant *wpa_s,
+ struct wpa_driver_ap_params *params)
{
- if (wpa_s->driver->set_beacon)
- return wpa_s->driver->set_beacon(wpa_s->drv_priv, head,
- head_len, tail, tail_len,
- dtim_period, beacon_int);
+ if (wpa_s->driver->set_ap)
+ return wpa_s->driver->set_ap(wpa_s->drv_priv, params);
return -1;
}
@@ -386,12 +352,13 @@ static inline int wpa_drv_send_action(struct wpa_supplicant *wpa_s,
unsigned int wait,
const u8 *dst, const u8 *src,
const u8 *bssid,
- const u8 *data, size_t data_len)
+ const u8 *data, size_t data_len,
+ int no_cck)
{
if (wpa_s->driver->send_action)
return wpa_s->driver->send_action(wpa_s->drv_priv, freq,
wait, dst, src, bssid,
- data, data_len);
+ data, data_len, no_cck);
return -1;
}
@@ -431,14 +398,6 @@ static inline int wpa_drv_if_remove(struct wpa_supplicant *wpa_s,
return -1;
}
-static inline int wpa_drv_set_intra_bss(struct wpa_supplicant *wpa_s,
- int enabled)
-{
- if (wpa_s->driver->set_intra_bss)
- return wpa_s->driver->set_intra_bss(wpa_s->drv_priv, enabled);
- return -1;
-}
-
static inline int wpa_drv_remain_on_channel(struct wpa_supplicant *wpa_s,
unsigned int freq,
unsigned int duration)
@@ -467,15 +426,6 @@ static inline int wpa_drv_probe_req_report(struct wpa_supplicant *wpa_s,
return -1;
}
-static inline int wpa_drv_disable_11b_rates(struct wpa_supplicant *wpa_s,
- int disabled)
-{
- if (wpa_s->driver->disable_11b_rates)
- return wpa_s->driver->disable_11b_rates(wpa_s->drv_priv,
- disabled);
- return -1;
-}
-
static inline int wpa_drv_deinit_ap(struct wpa_supplicant *wpa_s)
{
if (wpa_s->driver->deinit_ap)
@@ -619,12 +569,12 @@ static inline int wpa_drv_p2p_set_params(struct wpa_supplicant *wpa_s,
static inline int wpa_drv_p2p_prov_disc_req(struct wpa_supplicant *wpa_s,
const u8 *peer_addr,
- u16 config_methods)
+ u16 config_methods, int join)
{
if (!wpa_s->driver->p2p_prov_disc_req)
return -1;
return wpa_s->driver->p2p_prov_disc_req(wpa_s->drv_priv, peer_addr,
- config_methods);
+ config_methods, join);
}
static inline u64 wpa_drv_p2p_sd_request(struct wpa_supplicant *wpa_s,
@@ -704,6 +654,7 @@ static inline int wpa_drv_tdls_oper(struct wpa_supplicant *wpa_s,
return wpa_s->driver->tdls_oper(wpa_s->drv_priv, oper, peer);
}
+#ifdef ANDROID
static inline int wpa_drv_driver_cmd(struct wpa_supplicant *wpa_s,
char *cmd, char *buf, size_t buf_len)
{
@@ -711,5 +662,24 @@ static inline int wpa_drv_driver_cmd(struct wpa_supplicant *wpa_s,
return -1;
return wpa_s->driver->driver_cmd(wpa_s->drv_priv, cmd, buf, buf_len);
}
+#endif
+static inline void wpa_drv_set_rekey_info(struct wpa_supplicant *wpa_s,
+ const u8 *kek, const u8 *kck,
+ const u8 *replay_ctr)
+{
+ if (!wpa_s->driver->set_rekey_info)
+ return;
+ wpa_s->driver->set_rekey_info(wpa_s->drv_priv, kek, kck, replay_ctr);
+}
+
+#ifdef ANDROID_P2P
+static inline int wpa_drv_go_switch_channel(struct wpa_supplicant *wpa_s,
+ int freq)
+{
+ if (!wpa_s->driver->go_switch_channel)
+ return -1;
+ return wpa_s->driver->go_switch_channel(wpa_s->drv_priv, freq);
+}
+#endif
#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/eap_register.c b/wpa_supplicant/eap_register.c
index e5f43aa..b3faaa1 100644
--- a/wpa_supplicant/eap_register.c
+++ b/wpa_supplicant/eap_register.c
@@ -17,6 +17,7 @@
#include "common.h"
#include "eap_peer/eap_methods.h"
#include "eap_server/eap_methods.h"
+#include "wpa_supplicant_i.h"
/**
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
index 332a044..76f7527 100644
--- a/wpa_supplicant/eapol_test.c
+++ b/wpa_supplicant/eapol_test.c
@@ -24,6 +24,7 @@
#include "eap_peer/eap.h"
#include "eap_server/eap_methods.h"
#include "eloop.h"
+#include "utils/base64.h"
#include "rsn_supp/wpa.h"
#include "eap_peer/eap_i.h"
#include "wpa_supplicant_i.h"
@@ -76,6 +77,8 @@ struct eapol_test_data {
char *connect_info;
u8 own_addr[ETH_ALEN];
struct extra_radius_attr *extra_attrs;
+
+ FILE *server_cert_file;
};
static struct eapol_test_data eapol_test;
@@ -292,7 +295,6 @@ static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf,
size_t len)
{
- /* struct wpa_supplicant *wpa_s = ctx; */
printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n",
type, (unsigned long) len);
if (type == IEEE802_1X_TYPE_EAP_PACKET) {
@@ -306,16 +308,16 @@ static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf,
static void eapol_test_set_config_blob(void *ctx,
struct wpa_config_blob *blob)
{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_config_set_blob(wpa_s->conf, blob);
+ struct eapol_test_data *e = ctx;
+ wpa_config_set_blob(e->wpa_s->conf, blob);
}
static const struct wpa_config_blob *
eapol_test_get_config_blob(void *ctx, const char *name)
{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_config_get_blob(wpa_s->conf, name);
+ struct eapol_test_data *e = ctx;
+ return wpa_config_get_blob(e->wpa_s->conf, name);
}
@@ -384,6 +386,20 @@ static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx)
}
+static void eapol_test_write_cert(FILE *f, const char *subject,
+ const struct wpabuf *cert)
+{
+ unsigned char *encoded;
+
+ encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL);
+ if (encoded == NULL)
+ return;
+ fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s"
+ "-----END CERTIFICATE-----\n\n", subject, encoded);
+ os_free(encoded);
+}
+
+
static void eapol_test_cert_cb(void *ctx, int depth, const char *subject,
const char *cert_hash,
const struct wpabuf *cert)
@@ -409,6 +425,10 @@ static void eapol_test_cert_cb(void *ctx, int depth, const char *subject,
depth, subject, cert_hex);
os_free(cert_hex);
}
+
+ if (e->server_cert_file)
+ eapol_test_write_cert(e->server_cert_file,
+ subject, cert);
}
}
@@ -424,7 +444,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
printf("Failed to allocate EAPOL context.\n");
return -1;
}
- ctx->ctx = wpa_s;
+ ctx->ctx = e;
ctx->msg_ctx = wpa_s;
ctx->scard_ctx = wpa_s->scard;
ctx->cb = eapol_sm_cb;
@@ -439,6 +459,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
ctx->cert_cb = eapol_test_cert_cb;
+ ctx->cert_in_cb = 1;
wpa_s->eapol = eapol_sm_init(ctx);
if (wpa_s->eapol == NULL) {
@@ -995,7 +1016,7 @@ static void usage(void)
"eapol_test [-nWS] -c<conf> [-a<AS IP>] [-p<AS port>] "
"[-s<AS secret>]\\\n"
" [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
- " [-M<client MAC address>] \\\n"
+ " [-M<client MAC address>] [-o<server cert file] \\\n"
" [-N<attr spec>] \\\n"
" [-A<client IP>]\n"
"eapol_test scard\n"
@@ -1021,6 +1042,8 @@ static void usage(void)
" -M<client MAC address> = Set own MAC address "
"(Calling-Station-Id,\n"
" default: 02:00:00:00:00:01)\n"
+ " -o<server cert file> = Write received server certificate\n"
+ " chain to the specified file\n"
" -N<attr spec> = send arbitrary attribute specified by:\n"
" attr_id:syntax:value or attr_id\n"
" attr_id - number id of the attribute\n"
@@ -1062,7 +1085,7 @@ int main(int argc, char *argv[])
wpa_debug_show_keys = 1;
for (;;) {
- c = getopt(argc, argv, "a:A:c:C:M:nN:p:r:s:St:W");
+ c = getopt(argc, argv, "a:A:c:C:M:nN:o:p:r:s:St:W");
if (c < 0)
break;
switch (c) {
@@ -1087,6 +1110,16 @@ int main(int argc, char *argv[])
case 'n':
eapol_test.no_mppe_keys++;
break;
+ case 'o':
+ if (eapol_test.server_cert_file)
+ fclose(eapol_test.server_cert_file);
+ eapol_test.server_cert_file = fopen(optarg, "w");
+ if (eapol_test.server_cert_file == NULL) {
+ printf("Could not open '%s' for writing\n",
+ optarg);
+ return -1;
+ }
+ break;
case 'p':
as_port = atoi(optarg);
break;
@@ -1229,6 +1262,9 @@ int main(int argc, char *argv[])
eloop_destroy();
+ if (eapol_test.server_cert_file)
+ fclose(eapol_test.server_cert_file);
+
printf("MPPE keys OK: %d mismatch: %d\n",
eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch);
if (eapol_test.num_mppe_mismatch)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 2765aef..4bbd2e4 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -38,12 +38,13 @@
#include "wps_supplicant.h"
#include "ibss_rsn.h"
#include "sme.h"
+#include "gas_query.h"
#include "p2p_supplicant.h"
#include "bgscan.h"
#include "ap.h"
#include "bss.h"
-#include "mlme.h"
#include "scan.h"
+#include "offchannel.h"
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
@@ -69,11 +70,7 @@ static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the "
"current AP");
- if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
- WPA_KEY_MGMT_WPA_NONE |
- WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X |
- WPA_KEY_MGMT_PSK_SHA256 |
- WPA_KEY_MGMT_IEEE8021X_SHA256)) {
+ if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
u8 wpa_ie[80];
size_t wpa_ie_len = sizeof(wpa_ie);
wpa_supplicant_set_suites(wpa_s, NULL, ssid,
@@ -95,8 +92,7 @@ static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
}
-static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
- void *sock_ctx)
+void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -230,6 +226,7 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
#ifdef IEEE8021X_EAPOL
+#ifdef PCSC_FUNCS
int aka = 0, sim = 0, type;
if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL)
@@ -281,6 +278,7 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
}
wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
+#endif /* PCSC_FUNCS */
#endif /* IEEE8021X_EAPOL */
return 0;
@@ -476,6 +474,115 @@ static int freq_allowed(int *freqs, int freq)
}
+static int ht_supported(const struct hostapd_hw_modes *mode)
+{
+ if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
+ /*
+ * The driver did not indicate whether it supports HT. Assume
+ * it does to avoid connection issues.
+ */
+ return 1;
+ }
+
+ /*
+ * IEEE Std 802.11n-2009 20.1.1:
+ * An HT non-AP STA shall support all EQM rates for one spatial stream.
+ */
+ return mode->mcs_set[0] == 0xff;
+}
+
+
+static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss)
+{
+ const struct hostapd_hw_modes *mode = NULL, *modes;
+ const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
+ const u8 *rate_ie;
+ int i, j, k;
+
+ if (bss->freq == 0)
+ return 1; /* Cannot do matching without knowing band */
+
+ modes = wpa_s->hw.modes;
+ if (modes == NULL) {
+ /*
+ * The driver does not provide any additional information
+ * about the utilized hardware, so allow the connection attempt
+ * to continue.
+ */
+ return 1;
+ }
+
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
+ for (j = 0; j < modes[i].num_channels; j++) {
+ int freq = modes[i].channels[j].freq;
+ if (freq == bss->freq) {
+ if (mode &&
+ mode->mode == HOSTAPD_MODE_IEEE80211G)
+ break; /* do not allow 802.11b replace
+ * 802.11g */
+ mode = &modes[i];
+ break;
+ }
+ }
+ }
+
+ if (mode == NULL)
+ return 0;
+
+ for (i = 0; i < (int) sizeof(scan_ie); i++) {
+ rate_ie = wpa_scan_get_ie(bss, scan_ie[i]);
+ if (rate_ie == NULL)
+ continue;
+
+ for (j = 2; j < rate_ie[1] + 2; j++) {
+ int flagged = !!(rate_ie[j] & 0x80);
+ int r = (rate_ie[j] & 0x7f) * 5;
+
+ /*
+ * IEEE Std 802.11n-2009 7.3.2.2:
+ * The new BSS Membership selector value is encoded
+ * like a legacy basic rate, but it is not a rate and
+ * only indicates if the BSS members are required to
+ * support the mandatory features of Clause 20 [HT PHY]
+ * in order to join the BSS.
+ */
+ if (flagged && ((rate_ie[j] & 0x7f) ==
+ BSS_MEMBERSHIP_SELECTOR_HT_PHY)) {
+ if (!ht_supported(mode)) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ " hardware does not support "
+ "HT PHY");
+ return 0;
+ }
+ continue;
+ }
+
+ if (!flagged)
+ continue;
+
+ /* check for legacy basic rates */
+ for (k = 0; k < mode->num_rates; k++) {
+ if (mode->rates[k] == r)
+ break;
+ }
+ if (k == mode->num_rates) {
+ /*
+ * IEEE Std 802.11-2007 7.3.2.2 demands that in
+ * order to join a BSS all required rates
+ * have to be supported by the hardware.
+ */
+ wpa_dbg(wpa_s, MSG_DEBUG, " hardware does "
+ "not support required rate %d.%d Mbps",
+ r / 10, r % 10);
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+
static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
int i, struct wpa_scan_res *bss,
struct wpa_ssid *group)
@@ -561,6 +668,10 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_WPS */
+ if (ssid->bssid_set && ssid->ssid_len == 0 &&
+ os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0)
+ check_ssid = 0;
+
if (check_ssid &&
(ssid_len != ssid->ssid_len ||
os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
@@ -604,6 +715,12 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
continue;
}
+ if (!rate_match(wpa_s, bss)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, " skip - rate sets do "
+ "not match");
+ continue;
+ }
+
#ifdef CONFIG_P2P
/*
* TODO: skip the AP if its P2P IE has Group Formation
@@ -672,7 +789,8 @@ wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
break;
}
- if (selected == NULL && wpa_s->blacklist) {
+ if (selected == NULL && wpa_s->blacklist &&
+ !wpa_s->countermeasures) {
wpa_dbg(wpa_s, MSG_DEBUG, "No APs found - clear "
"blacklist and try again");
wpa_blacklist_clear(wpa_s);
@@ -700,35 +818,23 @@ static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
}
-#ifdef ANDROID_BRCM_P2P_PATCH
+
int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
-#else
-void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
-#endif /* ANDROID_BRCM_P2P_PATCH */
- struct wpa_bss *selected,
- struct wpa_ssid *ssid)
+ struct wpa_bss *selected,
+ struct wpa_ssid *ssid)
{
if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
"PBC session overlap");
#ifdef CONFIG_P2P
- if (wpas_p2p_notif_pbc_overlap(wpa_s) == 1) {
-#ifdef ANDROID_BRCM_P2P_PATCH
+ if (wpas_p2p_notif_pbc_overlap(wpa_s) == 1)
return -1;
-#else
- return;
-#endif
- }
#endif /* CONFIG_P2P */
#ifdef CONFIG_WPS
wpas_wps_cancel(wpa_s);
#endif /* CONFIG_WPS */
-#ifdef ANDROID_BRCM_P2P_PATCH
return -1;
-#else
- return;
-#endif /* ANDROID_BRCM_P2P_PATCH */
}
/*
@@ -736,12 +842,7 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
* reassociation is requested. If we are in process of associating with
* the selected BSSID, do not trigger new attempt.
*/
- if ((wpa_s->reassociate
-#ifdef ANDROID_BRCM_P2P_PATCH
- && (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0)
- && (wpa_s->wpa_state != WPA_COMPLETED)
-#endif
- )||
+ if (wpa_s->reassociate ||
(os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
((wpa_s->wpa_state != WPA_ASSOCIATING &&
wpa_s->wpa_state != WPA_AUTHENTICATING) ||
@@ -749,11 +850,7 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
0))) {
if (wpa_supplicant_scard_init(wpa_s, ssid)) {
wpa_supplicant_req_new_scan(wpa_s, 10, 0);
-#ifdef ANDROID_BRCM_P2P_PATCH
return 0;
-#else
- return;
-#endif
}
wpa_msg(wpa_s, MSG_DEBUG, "Request association: "
"reassociate: %d selected: "MACSTR " bssid: " MACSTR
@@ -766,9 +863,8 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with the "
"selected AP");
}
-#ifdef ANDROID_BRCM_P2P_PATCH
+
return 0;
-#endif
}
@@ -837,6 +933,9 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
if (wpa_s->current_ssid != ssid)
return 1; /* different network block */
+ if (wpas_driver_bss_selection(wpa_s))
+ return 0; /* Driver-based roaming */
+
for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *res = scan_res->res[i];
const u8 *ie;
@@ -912,6 +1011,18 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
wpa_supplicant_notify_scanning(wpa_s, 0);
+#ifdef CONFIG_P2P
+ if (wpa_s->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
+ wpa_s->global->p2p != NULL) {
+ wpa_s->p2p_cb_on_scan_complete = 0;
+ if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
+ "stopped scan processing");
+ return -1;
+ }
+ }
+#endif /* CONFIG_P2P */
+
scan_res = wpa_supplicant_get_scan_results(wpa_s,
data ? &data->scan_info :
NULL, 1);
@@ -980,7 +1091,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
return 0;
}
- if (bgscan_notify_scan(wpa_s, scan_res) == 1) {
+ if (!wpas_driver_bss_selection(wpa_s) &&
+ bgscan_notify_scan(wpa_s, scan_res) == 1) {
wpa_scan_results_free(scan_res);
return 0;
}
@@ -992,16 +1104,15 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid,
scan_res);
wpa_scan_results_free(scan_res);
- if (skip)
+ if (skip) {
+ wpa_supplicant_rsn_preauth_scan_results(wpa_s);
return 0;
-#ifdef ANDROID_BRCM_P2P_PATCH
+ }
+
if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Connect Failed");
+ wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed");
return -1;
}
-#else
- wpa_supplicant_connect(wpa_s, selected, ssid);
-#endif
wpa_supplicant_rsn_preauth_scan_results(wpa_s);
} else {
wpa_scan_results_free(scan_res);
@@ -1022,10 +1133,14 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
*/
timeout_sec = 0;
timeout_usec = 250000;
+ wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
+ timeout_usec);
+ return 0;
}
#endif /* CONFIG_P2P */
- wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
- timeout_usec);
+ if (wpa_supplicant_req_sched_scan(wpa_s))
+ wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
+ timeout_usec);
}
}
return 0;
@@ -1270,11 +1385,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
return;
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ||
- (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
- os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) {
+ if (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
+ os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
MACSTR, MAC2STR(bssid));
random_add_randomness(bssid, ETH_ALEN);
@@ -1427,12 +1539,22 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
}
+static int disconnect_reason_recoverable(u16 reason_code)
+{
+ return reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
+ reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
+ reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
+}
+
+
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
u16 reason_code)
{
const u8 *bssid;
int authenticating;
u8 prev_pending_bssid[ETH_ALEN];
+ struct wpa_bss *fast_reconnect = NULL;
+ struct wpa_ssid *fast_reconnect_ssid = NULL;
authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
@@ -1455,13 +1577,29 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
}
if (!wpa_s->auto_reconnect_disabled ||
wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Auto connect enabled: try to "
- "reconnect (wps=%d)",
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPS);
- if (wpa_s->wpa_state >= WPA_ASSOCIATING)
+ wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect enabled: try to "
+ "reconnect (wps=%d wpa_state=%d)",
+ wpa_s->key_mgmt == WPA_KEY_MGMT_WPS,
+ wpa_s->wpa_state);
+ if (wpa_s->wpa_state == WPA_COMPLETED &&
+ wpa_s->current_ssid &&
+ wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
+ disconnect_reason_recoverable(reason_code)) {
+ /*
+ * It looks like the AP has dropped association with
+ * us, but could allow us to get back in. Try to
+ * reconnect to the same BSS without full scan to save
+ * time for some common cases.
+ */
+ fast_reconnect = wpa_s->current_bss;
+ fast_reconnect_ssid = wpa_s->current_ssid;
+ } else if (wpa_s->wpa_state >= WPA_ASSOCIATING)
wpa_supplicant_req_scan(wpa_s, 0, 500000);
+ else
+ wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new "
+ "immediate scan");
} else {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Auto connect disabled: do not "
+ wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not "
"try to re-connect");
wpa_s->reassociate = 0;
wpa_s->disconnected = 1;
@@ -1469,7 +1607,8 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
bssid = wpa_s->bssid;
if (is_zero_ether_addr(bssid))
bssid = wpa_s->pending_bssid;
- wpas_connection_failed(wpa_s, bssid);
+ if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
+ wpas_connection_failed(wpa_s, bssid);
wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
" reason=%d",
@@ -1483,12 +1622,22 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
+
+ if (fast_reconnect) {
+#ifndef CONFIG_NO_SCAN_PROCESSING
+ wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS");
+ if (wpa_supplicant_connect(wpa_s, fast_reconnect,
+ fast_reconnect_ssid) < 0) {
+ /* Recover through full scan */
+ wpa_supplicant_req_scan(wpa_s, 0, 100000);
+ }
+#endif /* CONFIG_NO_SCAN_PROCESSING */
+ }
}
#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
-static void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx,
- void *sock_ctx)
+void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -1532,6 +1681,9 @@ wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
/* initialize countermeasures */
wpa_s->countermeasures = 1;
+
+ wpa_blacklist_add(wpa_s, wpa_s->bssid);
+
wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
/*
@@ -1667,9 +1819,8 @@ static void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s,
wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
break;
case TDLS_REQUEST_TEARDOWN:
- /* request from driver to add FTIE */
- wpa_tdls_recv_teardown_notify(wpa_s->wpa, data->tdls.peer,
- data->tdls.reason_code);
+ wpa_tdls_send_teardown(wpa_s->wpa, data->tdls.peer,
+ data->tdls.reason_code);
break;
}
}
@@ -1796,6 +1947,50 @@ static void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
}
+static void wnm_action_rx(struct wpa_supplicant *wpa_s, struct rx_action *rx)
+{
+ u8 action, mode;
+ const u8 *pos, *end;
+
+ if (rx->data == NULL || rx->len == 0)
+ return;
+
+ pos = rx->data;
+ end = pos + rx->len;
+ action = *pos++;
+
+ wpa_printf(MSG_DEBUG, "WNM: RX action %u from " MACSTR,
+ action, MAC2STR(rx->sa));
+ switch (action) {
+ case WNM_BSS_TRANS_MGMT_REQ:
+ if (pos + 5 > end)
+ break;
+ wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management "
+ "Request: dialog_token=%u request_mode=0x%x "
+ "disassoc_timer=%u validity_interval=%u",
+ pos[0], pos[1], WPA_GET_LE16(pos + 2), pos[4]);
+ mode = pos[1];
+ pos += 5;
+ if (mode & 0x08)
+ pos += 12; /* BSS Termination Duration */
+ if (mode & 0x10) {
+ char url[256];
+ if (pos + 1 > end || pos + 1 + pos[0] > end) {
+ wpa_printf(MSG_DEBUG, "WNM: Invalid BSS "
+ "Transition Management Request "
+ "(URL)");
+ break;
+ }
+ os_memcpy(url, pos + 1, pos[0]);
+ url[pos[0]] = '\0';
+ wpa_msg(wpa_s, MSG_INFO, "WNM: ESS Disassociation "
+ "Imminent - session_info_url=%s", url);
+ }
+ break;
+ }
+}
+
+
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
@@ -1804,14 +1999,33 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
event != EVENT_INTERFACE_ENABLED &&
- event != EVENT_INTERFACE_STATUS) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignore event %d while interface is "
- "disabled", event);
+ event != EVENT_INTERFACE_STATUS &&
+ event != EVENT_SCHED_SCAN_STOPPED) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Ignore event %s (%d) while interface is disabled",
+ event_to_string(event), event);
return;
}
- wpa_dbg(wpa_s, MSG_DEBUG, "Event %d received on interface %s",
- event, wpa_s->ifname);
+#ifndef CONFIG_NO_STDOUT_DEBUG
+{
+ int level = MSG_DEBUG;
+
+ if (event == EVENT_RX_MGMT && data && data->rx_mgmt.frame &&
+ data->rx_mgmt.frame_len >= 24) {
+ const struct ieee80211_hdr *hdr;
+ u16 fc;
+ hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
+ fc = le_to_host16(hdr->frame_control);
+ if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
+ WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
+ level = MSG_EXCESSIVE;
+ }
+
+ wpa_dbg(wpa_s, level, "Event %s (%d) received",
+ event_to_string(event), event);
+}
+#endif /* CONFIG_NO_STDOUT_DEBUG */
switch (event) {
case EVENT_AUTH:
@@ -1835,6 +2049,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->disassoc_info.addr);
break;
}
+ if (wpa_s->ap_iface) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Ignore disassoc event in "
+ "AP mode");
+ break;
+ }
#endif /* CONFIG_AP */
if (data) {
reason_code = data->disassoc_info.reason_code;
@@ -1884,13 +2103,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->deauth_info.addr);
break;
}
+ if (wpa_s->ap_iface) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Ignore deauth event in "
+ "AP mode");
+ break;
+ }
#endif /* CONFIG_AP */
wpa_supplicant_event_disassoc(wpa_s, reason_code);
-
-#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_P2P)
- wpas_p2p_group_remove_notif(wpa_s, reason_code);
-#endif
-
break;
case EVENT_MICHAEL_MIC_FAILURE:
wpa_supplicant_event_michael_mic_failure(wpa_s, data);
@@ -1950,27 +2169,28 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
sme_event_assoc_timed_out(wpa_s, data);
break;
-#ifdef CONFIG_AP
case EVENT_TX_STATUS:
wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS dst=" MACSTR
" type=%d stype=%d",
MAC2STR(data->tx_status.dst),
data->tx_status.type, data->tx_status.stype);
+#ifdef CONFIG_AP
if (wpa_s->ap_iface == NULL) {
-#ifdef CONFIG_P2P
+#ifdef CONFIG_OFFCHANNEL
if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
data->tx_status.stype == WLAN_FC_STYPE_ACTION)
- wpas_send_action_tx_status(
+ offchannel_send_action_tx_status(
wpa_s, data->tx_status.dst,
data->tx_status.data,
data->tx_status.data_len,
data->tx_status.ack ?
- P2P_SEND_ACTION_SUCCESS :
- P2P_SEND_ACTION_NO_ACK);
-#endif /* CONFIG_P2P */
+ OFFCHANNEL_SEND_ACTION_SUCCESS :
+ OFFCHANNEL_SEND_ACTION_NO_ACK);
+#endif /* CONFIG_OFFCHANNEL */
break;
}
-#ifdef CONFIG_P2P
+#endif /* CONFIG_AP */
+#ifdef CONFIG_OFFCHANNEL
wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst="
MACSTR, MAC2STR(wpa_s->parent->pending_action_dst));
/*
@@ -1981,16 +2201,17 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
os_memcmp(wpa_s->parent->pending_action_dst,
data->tx_status.dst, ETH_ALEN) == 0) {
- wpas_send_action_tx_status(
+ offchannel_send_action_tx_status(
wpa_s->parent, data->tx_status.dst,
data->tx_status.data,
data->tx_status.data_len,
data->tx_status.ack ?
- P2P_SEND_ACTION_SUCCESS :
- P2P_SEND_ACTION_NO_ACK);
+ OFFCHANNEL_SEND_ACTION_SUCCESS :
+ OFFCHANNEL_SEND_ACTION_NO_ACK);
break;
}
-#endif /* CONFIG_P2P */
+#endif /* CONFIG_OFFCHANNEL */
+#ifdef CONFIG_AP
switch (data->tx_status.type) {
case WLAN_FC_TYPE_MGMT:
ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
@@ -2005,12 +2226,23 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->tx_status.ack);
break;
}
+#endif /* CONFIG_AP */
+ break;
+#ifdef CONFIG_AP
+ case EVENT_EAPOL_TX_STATUS:
+ ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst,
+ data->eapol_tx_status.data,
+ data->eapol_tx_status.data_len,
+ data->eapol_tx_status.ack);
+ break;
+ case EVENT_DRIVER_CLIENT_POLL_OK:
+ ap_client_poll_ok(wpa_s, data->client_poll.addr);
break;
case EVENT_RX_FROM_UNKNOWN:
if (wpa_s->ap_iface == NULL)
break;
- ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.frame,
- data->rx_from_unknown.len);
+ ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr,
+ data->rx_from_unknown.wds);
break;
case EVENT_RX_MGMT:
if (wpa_s->ap_iface == NULL) {
@@ -2028,26 +2260,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
size_t ie_len = data->rx_mgmt.frame_len -
(mgmt->u.probe_req.variable -
data->rx_mgmt.frame);
- #ifdef ANDROID_BRCM_P2P_PATCH
- wpa_printf(MSG_DEBUG, "Non-AP: Probe request frame ");
- {
- /* If we are Go or client, we need not reply the probe reqest on eth0 interface */
- struct wpa_supplicant* ifs;
- int ignore = 0;
- for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
- if ( (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO ) ||(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT )) {
- wpa_printf(MSG_DEBUG, "Non-AP: NEERAJKG Ignoring Probe request");
- ignore = 1;
- break;
- }
- }
- if(ignore)
- break;
- else
- wpa_printf(MSG_DEBUG, "Non-AP: Couln't Ignore Probe request %d", wpa_s->p2p_group_interface);
- }
- #endif
- wpas_p2p_probe_req_rx(wpa_s, src, ie, ie_len);
+ wpas_p2p_probe_req_rx(wpa_s, src, mgmt->da,
+ mgmt->bssid, ie, ie_len);
break;
}
#endif /* CONFIG_P2P */
@@ -2081,6 +2295,28 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
}
#endif /* CONFIG_SME */
#endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_GAS
+ if (data->rx_action.category == WLAN_ACTION_PUBLIC &&
+ gas_query_rx(wpa_s->gas, data->rx_action.da,
+ data->rx_action.sa, data->rx_action.bssid,
+ data->rx_action.data, data->rx_action.len,
+ data->rx_action.freq) == 0)
+ break;
+#endif /* CONFIG_GAS */
+ if (data->rx_action.category == WLAN_ACTION_WNM) {
+ wnm_action_rx(wpa_s, &data->rx_action);
+ break;
+ }
+#ifdef CONFIG_TDLS
+ if (data->rx_action.category == WLAN_ACTION_PUBLIC &&
+ data->rx_action.len >= 4 &&
+ data->rx_action.data[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "TDLS: Received Discovery "
+ "Response from " MACSTR,
+ MAC2STR(data->rx_action.sa));
+ break;
+ }
+#endif /* CONFIG_TDLS */
#ifdef CONFIG_P2P
wpas_p2p_rx_action(wpa_s, data->rx_action.da,
data->rx_action.sa,
@@ -2098,6 +2334,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (wpa_s->ap_iface) {
hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
data->rx_probe_req.sa,
+ data->rx_probe_req.da,
+ data->rx_probe_req.bssid,
data->rx_probe_req.ie,
data->rx_probe_req.ie_len);
break;
@@ -2105,20 +2343,35 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#endif /* CONFIG_AP */
#ifdef CONFIG_P2P
wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
+ data->rx_probe_req.da,
+ data->rx_probe_req.bssid,
data->rx_probe_req.ie,
data->rx_probe_req.ie_len);
#endif /* CONFIG_P2P */
break;
-#ifdef CONFIG_P2P
case EVENT_REMAIN_ON_CHANNEL:
+#ifdef CONFIG_OFFCHANNEL
+ offchannel_remain_on_channel_cb(
+ wpa_s, data->remain_on_channel.freq,
+ data->remain_on_channel.duration);
+#endif /* CONFIG_OFFCHANNEL */
+#ifdef CONFIG_P2P
wpas_p2p_remain_on_channel_cb(
wpa_s, data->remain_on_channel.freq,
data->remain_on_channel.duration);
+#endif /* CONFIG_P2P */
break;
case EVENT_CANCEL_REMAIN_ON_CHANNEL:
+#ifdef CONFIG_OFFCHANNEL
+ offchannel_cancel_remain_on_channel_cb(
+ wpa_s, data->remain_on_channel.freq);
+#endif /* CONFIG_OFFCHANNEL */
+#ifdef CONFIG_P2P
wpas_p2p_cancel_remain_on_channel_cb(
wpa_s, data->remain_on_channel.freq);
+#endif /* CONFIG_P2P */
break;
+#ifdef CONFIG_P2P
case EVENT_P2P_DEV_FOUND: {
struct p2p_peer_info peer_info;
@@ -2161,7 +2414,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->p2p_prov_disc_req.dev_name,
data->p2p_prov_disc_req.supp_config_methods,
data->p2p_prov_disc_req.dev_capab,
- data->p2p_prov_disc_req.group_capab);
+ data->p2p_prov_disc_req.group_capab,
+ NULL, 0);
break;
case EVENT_P2P_PROV_DISC_RESPONSE:
wpas_prov_disc_resp(wpa_s, data->p2p_prov_disc_resp.peer,
@@ -2182,18 +2436,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->p2p_sd_resp.tlvs_len);
break;
#endif /* CONFIG_P2P */
-#ifdef CONFIG_CLIENT_MLME
- case EVENT_MLME_RX: {
- struct ieee80211_rx_status rx_status;
- os_memset(&rx_status, 0, sizeof(rx_status));
- rx_status.freq = data->mlme_rx.freq;
- rx_status.channel = data->mlme_rx.channel;
- rx_status.ssi = data->mlme_rx.ssi;
- ieee80211_sta_rx(wpa_s, data->mlme_rx.buf, data->mlme_rx.len,
- &rx_status);
- break;
- }
-#endif /* CONFIG_CLIENT_MLME */
case EVENT_EAPOL_RX:
wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
data->eapol_rx.data,
@@ -2209,6 +2451,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
case EVENT_INTERFACE_ENABLED:
wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+ wpa_supplicant_update_mac_addr(wpa_s);
#ifdef CONFIG_AP
if (!wpa_s->ap_iface) {
wpa_supplicant_set_state(wpa_s,
@@ -2268,12 +2511,44 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
hostapd_event_sta_low_ack(wpa_s->ap_iface->bss[0],
data->low_ack.addr);
#endif /* CONFIG_AP */
+#ifdef CONFIG_TDLS
+ if (data)
+ wpa_tdls_disable_link(wpa_s->wpa, data->low_ack.addr);
+#endif /* CONFIG_TDLS */
break;
case EVENT_IBSS_PEER_LOST:
#ifdef CONFIG_IBSS_RSN
ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
#endif /* CONFIG_IBSS_RSN */
break;
+ case EVENT_DRIVER_GTK_REKEY:
+ if (os_memcmp(data->driver_gtk_rekey.bssid,
+ wpa_s->bssid, ETH_ALEN))
+ break;
+ if (!wpa_s->wpa)
+ break;
+ wpa_sm_update_replay_ctr(wpa_s->wpa,
+ data->driver_gtk_rekey.replay_ctr);
+ break;
+ case EVENT_SCHED_SCAN_STOPPED:
+ wpa_s->sched_scanning = 0;
+ wpa_supplicant_notify_scanning(wpa_s, 0);
+
+ if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
+ break;
+
+ /*
+ * If we timed out, start a new sched scan to continue
+ * searching for more SSIDs.
+ */
+ if (wpa_s->sched_scan_timed_out)
+ wpa_supplicant_req_sched_scan(wpa_s);
+ break;
+ case EVENT_WPS_BUTTON_PUSHED:
+#ifdef CONFIG_WPS
+ wpas_wps_start_pbc(wpa_s, NULL, 0);
+#endif /* CONFIG_WPS */
+ break;
default:
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
break;
diff --git a/wpa_supplicant/examples/udhcpd-p2p.conf b/wpa_supplicant/examples/udhcpd-p2p.conf
index b94f94f..df59094 100644
--- a/wpa_supplicant/examples/udhcpd-p2p.conf
+++ b/wpa_supplicant/examples/udhcpd-p2p.conf
@@ -62,12 +62,12 @@ interface wlan2 #default: eth0
# The location of the pid file
pidfile /var/run/udhcpd-wlan2.pid #default: /var/run/udhcpd.pid
-# Everytime udhcpd writes a leases file, the below script will be called.
+# Every time udhcpd writes a leases file, the below script will be called.
# Useful for writing the lease file to flash every few hours.
#notify_file #default: (no script)
-#notify_file dumpleases # <--- usefull for debugging
+#notify_file dumpleases # <--- useful for debugging
# The following are bootp specific options, setable by udhcpd.
diff --git a/wpa_supplicant/examples/wps-ap-cli b/wpa_supplicant/examples/wps-ap-cli
new file mode 100755
index 0000000..7c6b0aa
--- /dev/null
+++ b/wpa_supplicant/examples/wps-ap-cli
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+CLI=wpa_cli
+
+pbc()
+{
+ echo "Starting PBC mode"
+ echo "Push button on the station within two minutes"
+ if ! $CLI wps_pbc | grep -q OK; then
+ echo "Failed to enable PBC mode"
+ fi
+}
+
+enter_pin()
+{
+ echo "Enter a PIN from a station to be enrolled to the network."
+ read -p "Enrollee PIN: " pin
+ cpin=`$CLI wps_check_pin "$pin" | tail -1`
+ if [ "$cpin" = "FAIL-CHECKSUM" ]; then
+ echo "Checksum digit is not valid"
+ read -p "Do you want to use this PIN (y/n)? " resp
+ case "$resp" in
+ y*)
+ cpin=`echo "$pin" | sed "s/[^1234567890]//g"`
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ fi
+ if [ "$cpin" = "FAIL" ]; then
+ echo "Invalid PIN: $pin"
+ return 1
+ fi
+ echo "Enabling Enrollee PIN: $cpin"
+ $CLI wps_pin any "$cpin"
+}
+
+show_config()
+{
+ $CLI status wps
+}
+
+main_menu()
+{
+ echo "WPS AP"
+ echo "------"
+ echo "1: Push button (activate PBC)"
+ echo "2: Enter Enrollee PIN"
+ echo "3: Show current configuration"
+ echo "0: Exit wps-ap-cli"
+
+ read -p "Command: " cmd
+
+ case "$cmd" in
+ 1)
+ pbc
+ ;;
+ 2)
+ enter_pin
+ ;;
+ 3)
+ show_config
+ ;;
+ 0)
+ exit 0
+ ;;
+ *)
+ echo "Unknown command: $cmd"
+ ;;
+ esac
+
+ echo
+ main_menu
+}
+
+
+main_menu
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
new file mode 100644
index 0000000..3b736da
--- /dev/null
+++ b/wpa_supplicant/gas_query.c
@@ -0,0 +1,481 @@
+/*
+ * Generic advertisement service (GAS) query
+ * Copyright (c) 2009, Atheros Communications
+ * Copyright (c) 2011, Qualcomm Atheros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "utils/eloop.h"
+#include "common/ieee802_11_defs.h"
+#include "common/gas.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+#include "offchannel.h"
+#include "gas_query.h"
+
+
+#define GAS_QUERY_TIMEOUT 5
+
+
+struct gas_query_pending {
+ struct dl_list list;
+ u8 addr[ETH_ALEN];
+ u8 dialog_token;
+ u8 next_frag_id;
+ unsigned int wait_comeback:1;
+ unsigned int offchannel_tx_started:1;
+ int freq;
+ u16 status_code;
+ struct wpabuf *adv_proto;
+ struct wpabuf *resp;
+ void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
+ enum gas_query_result result,
+ const struct wpabuf *adv_proto,
+ const struct wpabuf *resp, u16 status_code);
+ void *ctx;
+};
+
+struct gas_query {
+ struct wpa_supplicant *wpa_s;
+ struct dl_list pending; /* struct gas_query_pending */
+};
+
+
+static void gas_query_tx_comeback_timeout(void *eloop_data, void *user_ctx);
+static void gas_query_timeout(void *eloop_data, void *user_ctx);
+
+
+struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s)
+{
+ struct gas_query *gas;
+
+ gas = os_zalloc(sizeof(*gas));
+ if (gas == NULL)
+ return NULL;
+
+ gas->wpa_s = wpa_s;
+ dl_list_init(&gas->pending);
+
+ return gas;
+}
+
+
+static void gas_query_done(struct gas_query *gas,
+ struct gas_query_pending *query,
+ enum gas_query_result result)
+{
+ if (query->offchannel_tx_started)
+ offchannel_send_action_done(gas->wpa_s);
+ eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
+ eloop_cancel_timeout(gas_query_timeout, gas, query);
+ dl_list_del(&query->list);
+ query->cb(query->ctx, query->addr, query->dialog_token, result,
+ query->adv_proto, query->resp, query->status_code);
+ wpabuf_free(query->adv_proto);
+ wpabuf_free(query->resp);
+ os_free(query);
+}
+
+
+void gas_query_deinit(struct gas_query *gas)
+{
+ struct gas_query_pending *query, *next;
+
+ if (gas == NULL)
+ return;
+
+ dl_list_for_each_safe(query, next, &gas->pending,
+ struct gas_query_pending, list)
+ gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
+
+ os_free(gas);
+}
+
+
+static struct gas_query_pending *
+gas_query_get_pending(struct gas_query *gas, const u8 *addr, u8 dialog_token)
+{
+ struct gas_query_pending *q;
+ dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
+ if (os_memcmp(q->addr, addr, ETH_ALEN) == 0 &&
+ q->dialog_token == dialog_token)
+ return q;
+ }
+ return NULL;
+}
+
+
+static int gas_query_append(struct gas_query_pending *query, const u8 *data,
+ size_t len)
+{
+ if (wpabuf_resize(&query->resp, len) < 0) {
+ wpa_printf(MSG_DEBUG, "GAS: No memory to store the response");
+ return -1;
+ }
+ wpabuf_put_data(query->resp, data, len);
+ return 0;
+}
+
+
+static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
+ struct wpabuf *req)
+{
+ int res;
+ wpa_printf(MSG_DEBUG, "GAS: Send action frame to " MACSTR " len=%u "
+ "freq=%d", MAC2STR(query->addr),
+ (unsigned int) wpabuf_len(req), query->freq);
+ res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
+ gas->wpa_s->own_addr, query->addr,
+ wpabuf_head(req), wpabuf_len(req), 1000,
+ NULL, 0);
+ if (res == 0)
+ query->offchannel_tx_started = 1;
+ return res;
+}
+
+
+static void gas_query_tx_comeback_req(struct gas_query *gas,
+ struct gas_query_pending *query)
+{
+ struct wpabuf *req;
+
+ req = gas_build_comeback_req(query->dialog_token);
+ if (req == NULL) {
+ gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
+ return;
+ }
+
+ if (gas_query_tx(gas, query, req) < 0) {
+ wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
+ MACSTR, MAC2STR(query->addr));
+ gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
+ }
+
+ wpabuf_free(req);
+}
+
+
+static void gas_query_tx_comeback_timeout(void *eloop_data, void *user_ctx)
+{
+ struct gas_query *gas = eloop_data;
+ struct gas_query_pending *query = user_ctx;
+
+ wpa_printf(MSG_DEBUG, "GAS: Comeback timeout for request to " MACSTR,
+ MAC2STR(query->addr));
+ gas_query_tx_comeback_req(gas, query);
+}
+
+
+static void gas_query_tx_comeback_req_delay(struct gas_query *gas,
+ struct gas_query_pending *query,
+ u16 comeback_delay)
+{
+ unsigned int secs, usecs;
+
+ secs = (comeback_delay * 1024) / 1000000;
+ usecs = comeback_delay * 1024 - secs * 1000000;
+ wpa_printf(MSG_DEBUG, "GAS: Send comeback request to " MACSTR
+ " in %u secs %u usecs", MAC2STR(query->addr), secs, usecs);
+ eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
+ eloop_register_timeout(secs, usecs, gas_query_tx_comeback_timeout,
+ gas, query);
+}
+
+
+static void gas_query_rx_initial(struct gas_query *gas,
+ struct gas_query_pending *query,
+ const u8 *adv_proto, const u8 *resp,
+ size_t len, u16 comeback_delay)
+{
+ wpa_printf(MSG_DEBUG, "GAS: Received initial response from "
+ MACSTR " (dialog_token=%u comeback_delay=%u)",
+ MAC2STR(query->addr), query->dialog_token, comeback_delay);
+
+ query->adv_proto = wpabuf_alloc_copy(adv_proto, 2 + adv_proto[1]);
+ if (query->adv_proto == NULL) {
+ gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
+ return;
+ }
+
+ if (comeback_delay) {
+ query->wait_comeback = 1;
+ gas_query_tx_comeback_req_delay(gas, query, comeback_delay);
+ return;
+ }
+
+ /* Query was completed without comeback mechanism */
+ if (gas_query_append(query, resp, len) < 0) {
+ gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
+ return;
+ }
+
+ gas_query_done(gas, query, GAS_QUERY_SUCCESS);
+}
+
+
+static void gas_query_rx_comeback(struct gas_query *gas,
+ struct gas_query_pending *query,
+ const u8 *adv_proto, const u8 *resp,
+ size_t len, u8 frag_id, u8 more_frags,
+ u16 comeback_delay)
+{
+ wpa_printf(MSG_DEBUG, "GAS: Received comeback response from "
+ MACSTR " (dialog_token=%u frag_id=%u more_frags=%u "
+ "comeback_delay=%u)",
+ MAC2STR(query->addr), query->dialog_token, frag_id,
+ more_frags, comeback_delay);
+
+ if ((size_t) 2 + adv_proto[1] != wpabuf_len(query->adv_proto) ||
+ os_memcmp(adv_proto, wpabuf_head(query->adv_proto),
+ wpabuf_len(query->adv_proto)) != 0) {
+ wpa_printf(MSG_DEBUG, "GAS: Advertisement Protocol changed "
+ "between initial and comeback response from "
+ MACSTR, MAC2STR(query->addr));
+ gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
+ return;
+ }
+
+ if (comeback_delay) {
+ if (frag_id) {
+ wpa_printf(MSG_DEBUG, "GAS: Invalid comeback response "
+ "with non-zero frag_id and comeback_delay "
+ "from " MACSTR, MAC2STR(query->addr));
+ gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
+ return;
+ }
+ gas_query_tx_comeback_req_delay(gas, query, comeback_delay);
+ return;
+ }
+
+ if (frag_id != query->next_frag_id) {
+ wpa_printf(MSG_DEBUG, "GAS: Unexpected frag_id in response "
+ "from " MACSTR, MAC2STR(query->addr));
+ gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
+ return;
+ }
+ query->next_frag_id++;
+
+ if (gas_query_append(query, resp, len) < 0) {
+ gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
+ return;
+ }
+
+ if (more_frags) {
+ gas_query_tx_comeback_req(gas, query);
+ return;
+ }
+
+ gas_query_done(gas, query, GAS_QUERY_SUCCESS);
+}
+
+
+int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
+ const u8 *bssid, const u8 *data, size_t len, int freq)
+{
+ struct gas_query_pending *query;
+ u8 action, dialog_token, frag_id = 0, more_frags = 0;
+ u16 comeback_delay, resp_len;
+ const u8 *pos, *adv_proto;
+
+ if (gas == NULL || len < 4)
+ return -1;
+
+ pos = data;
+ action = *pos++;
+ dialog_token = *pos++;
+
+ if (action != WLAN_PA_GAS_INITIAL_RESP &&
+ action != WLAN_PA_GAS_COMEBACK_RESP)
+ return -1; /* Not a GAS response */
+
+ query = gas_query_get_pending(gas, sa, dialog_token);
+ if (query == NULL) {
+ wpa_printf(MSG_DEBUG, "GAS: No pending query found for " MACSTR
+ " dialog token %u", MAC2STR(sa), dialog_token);
+ return -1;
+ }
+
+ if (query->wait_comeback && action == WLAN_PA_GAS_INITIAL_RESP) {
+ wpa_printf(MSG_DEBUG, "GAS: Unexpected initial response from "
+ MACSTR " dialog token %u when waiting for comeback "
+ "response", MAC2STR(sa), dialog_token);
+ return 0;
+ }
+
+ if (!query->wait_comeback && action == WLAN_PA_GAS_COMEBACK_RESP) {
+ wpa_printf(MSG_DEBUG, "GAS: Unexpected comeback response from "
+ MACSTR " dialog token %u when waiting for initial "
+ "response", MAC2STR(sa), dialog_token);
+ return 0;
+ }
+
+ query->status_code = WPA_GET_LE16(pos);
+ pos += 2;
+
+ if (query->status_code != WLAN_STATUS_SUCCESS) {
+ wpa_printf(MSG_DEBUG, "GAS: Query to " MACSTR " dialog token "
+ "%u failed - status code %u",
+ MAC2STR(sa), dialog_token, query->status_code);
+ gas_query_done(gas, query, GAS_QUERY_FAILURE);
+ return 0;
+ }
+
+ if (action == WLAN_PA_GAS_COMEBACK_RESP) {
+ if (pos + 1 > data + len)
+ return 0;
+ frag_id = *pos & 0x7f;
+ more_frags = (*pos & 0x80) >> 7;
+ pos++;
+ }
+
+ /* Comeback Delay */
+ if (pos + 2 > data + len)
+ return 0;
+ comeback_delay = WPA_GET_LE16(pos);
+ pos += 2;
+
+ /* Advertisement Protocol element */
+ if (pos + 2 > data + len || pos + 2 + pos[1] > data + len) {
+ wpa_printf(MSG_DEBUG, "GAS: No room for Advertisement "
+ "Protocol element in the response from " MACSTR,
+ MAC2STR(sa));
+ return 0;
+ }
+
+ if (*pos != WLAN_EID_ADV_PROTO) {
+ wpa_printf(MSG_DEBUG, "GAS: Unexpected Advertisement "
+ "Protocol element ID %u in response from " MACSTR,
+ *pos, MAC2STR(sa));
+ return 0;
+ }
+
+ adv_proto = pos;
+ pos += 2 + pos[1];
+
+ /* Query Response Length */
+ if (pos + 2 > data + len) {
+ wpa_printf(MSG_DEBUG, "GAS: No room for GAS Response Length");
+ return 0;
+ }
+ resp_len = WPA_GET_LE16(pos);
+ pos += 2;
+
+ if (pos + resp_len > data + len) {
+ wpa_printf(MSG_DEBUG, "GAS: Truncated Query Response in "
+ "response from " MACSTR, MAC2STR(sa));
+ return 0;
+ }
+
+ if (pos + resp_len < data + len) {
+ wpa_printf(MSG_DEBUG, "GAS: Ignore %u octets of extra data "
+ "after Query Response from " MACSTR,
+ (unsigned int) (data + len - pos - resp_len),
+ MAC2STR(sa));
+ }
+
+ if (action == WLAN_PA_GAS_COMEBACK_RESP)
+ gas_query_rx_comeback(gas, query, adv_proto, pos, resp_len,
+ frag_id, more_frags, comeback_delay);
+ else
+ gas_query_rx_initial(gas, query, adv_proto, pos, resp_len,
+ comeback_delay);
+
+ return 0;
+}
+
+
+static void gas_query_timeout(void *eloop_data, void *user_ctx)
+{
+ struct gas_query *gas = eloop_data;
+ struct gas_query_pending *query = user_ctx;
+
+ wpa_printf(MSG_DEBUG, "GAS: No response received for query to " MACSTR,
+ MAC2STR(query->addr));
+ gas_query_done(gas, query, GAS_QUERY_TIMEOUT);
+}
+
+
+static int gas_query_dialog_token_available(struct gas_query *gas,
+ const u8 *dst, u8 dialog_token)
+{
+ struct gas_query_pending *q;
+ dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
+ if (os_memcmp(dst, q->addr, ETH_ALEN) == 0 &&
+ dialog_token == q->dialog_token)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
+ struct wpabuf *req,
+ void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
+ enum gas_query_result result,
+ const struct wpabuf *adv_proto,
+ const struct wpabuf *resp, u16 status_code),
+ void *ctx)
+{
+ struct gas_query_pending *query;
+ int dialog_token;
+
+ if (wpabuf_len(req) < 3)
+ return -1;
+
+ for (dialog_token = 0; dialog_token < 256; dialog_token++) {
+ if (gas_query_dialog_token_available(gas, dst, dialog_token))
+ break;
+ }
+ if (dialog_token == 256)
+ return -1; /* Too many pending queries */
+
+ query = os_zalloc(sizeof(*query));
+ if (query == NULL)
+ return -1;
+
+ os_memcpy(query->addr, dst, ETH_ALEN);
+ query->dialog_token = dialog_token;
+ query->freq = freq;
+ query->cb = cb;
+ query->ctx = ctx;
+ dl_list_add(&gas->pending, &query->list);
+
+ *(wpabuf_mhead_u8(req) + 2) = dialog_token;
+
+ wpa_printf(MSG_DEBUG, "GAS: Starting request for " MACSTR
+ " dialog_token %u", MAC2STR(dst), dialog_token);
+ if (gas_query_tx(gas, query, req) < 0) {
+ wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
+ MACSTR, MAC2STR(query->addr));
+ os_free(query);
+ return -1;
+ }
+
+ eloop_register_timeout(GAS_QUERY_TIMEOUT, 0, gas_query_timeout,
+ gas, query);
+
+ return dialog_token;
+}
+
+
+void gas_query_cancel(struct gas_query *gas, const u8 *dst, u8 dialog_token)
+{
+ struct gas_query_pending *query;
+
+ query = gas_query_get_pending(gas, dst, dialog_token);
+ if (query)
+ gas_query_done(gas, query, GAS_QUERY_CANCELLED);
+
+}
diff --git a/wpa_supplicant/gas_query.h b/wpa_supplicant/gas_query.h
new file mode 100644
index 0000000..64c3825
--- /dev/null
+++ b/wpa_supplicant/gas_query.h
@@ -0,0 +1,61 @@
+/*
+ * Generic advertisement service (GAS) query
+ * Copyright (c) 2009, Atheros Communications
+ * Copyright (c) 2011, Qualcomm Atheros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef GAS_QUERY_H
+#define GAS_QUERY_H
+
+struct gas_query;
+
+#ifdef CONFIG_GAS
+
+struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s);
+void gas_query_deinit(struct gas_query *gas);
+int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
+ const u8 *bssid, const u8 *data, size_t len, int freq);
+
+enum gas_query_result {
+ GAS_QUERY_SUCCESS,
+ GAS_QUERY_FAILURE,
+ GAS_QUERY_TIMEOUT,
+ GAS_QUERY_PEER_ERROR,
+ GAS_QUERY_INTERNAL_ERROR,
+ GAS_QUERY_CANCELLED,
+ GAS_QUERY_DELETED_AT_DEINIT
+};
+
+int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
+ struct wpabuf *req,
+ void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
+ enum gas_query_result result,
+ const struct wpabuf *adv_proto,
+ const struct wpabuf *resp, u16 status_code),
+ void *ctx);
+void gas_query_cancel(struct gas_query *gas, const u8 *dst, u8 dialog_token);
+
+#else /* CONFIG_GAS */
+
+static inline struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s)
+{
+ return (void *) 1;
+}
+
+static inline void gas_query_deinit(struct gas_query *gas)
+{
+}
+
+#endif /* CONFIG_GAS */
+
+
+#endif /* GAS_QUERY_H */
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 0d7d568..d4fa39d 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -168,8 +168,8 @@ static void supp_deauthenticate(void * ctx, int reason_code)
}
-int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr,
- const u8 *psk)
+static int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr,
+ const u8 *psk)
{
struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx));
if (ctx == NULL)
@@ -339,6 +339,8 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
return -1;
}
+ wpa_init_keys(ibss_rsn->auth_group);
+
return 0;
}
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
new file mode 100644
index 0000000..d42aa40
--- /dev/null
+++ b/wpa_supplicant/interworking.c
@@ -0,0 +1,1138 @@
+/*
+ * Interworking (IEEE 802.11u)
+ * Copyright (c) 2011, Qualcomm Atheros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "common/ieee802_11_defs.h"
+#include "common/gas.h"
+#include "common/wpa_ctrl.h"
+#include "drivers/driver.h"
+#include "eap_common/eap_defs.h"
+#include "eap_peer/eap_methods.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+#include "bss.h"
+#include "scan.h"
+#include "notify.h"
+#include "gas_query.h"
+#include "interworking.h"
+
+
+#if defined(EAP_SIM) | defined(EAP_SIM_DYNAMIC)
+#define INTERWORKING_3GPP
+#else
+#if defined(EAP_AKA) | defined(EAP_AKA_DYNAMIC)
+#define INTERWORKING_3GPP
+#else
+#if defined(EAP_AKA_PRIME) | defined(EAP_AKA_PRIME_DYNAMIC)
+#define INTERWORKING_3GPP
+#endif
+#endif
+#endif
+
+static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s);
+
+
+static struct wpabuf * anqp_build_req(u16 info_ids[], size_t num_ids,
+ struct wpabuf *extra)
+{
+ struct wpabuf *buf;
+ size_t i;
+ u8 *len_pos;
+
+ buf = gas_anqp_build_initial_req(0, 4 + num_ids * 2 +
+ (extra ? wpabuf_len(extra) : 0));
+ if (buf == NULL)
+ return NULL;
+
+ len_pos = gas_anqp_add_element(buf, ANQP_QUERY_LIST);
+ for (i = 0; i < num_ids; i++)
+ wpabuf_put_le16(buf, info_ids[i]);
+ gas_anqp_set_element_len(buf, len_pos);
+ if (extra)
+ wpabuf_put_buf(buf, extra);
+
+ gas_anqp_set_len(buf);
+
+ return buf;
+}
+
+
+static void interworking_anqp_resp_cb(void *ctx, const u8 *dst,
+ u8 dialog_token,
+ enum gas_query_result result,
+ const struct wpabuf *adv_proto,
+ const struct wpabuf *resp,
+ u16 status_code)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ anqp_resp_cb(wpa_s, dst, dialog_token, result, adv_proto, resp,
+ status_code);
+ interworking_next_anqp_fetch(wpa_s);
+}
+
+
+static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss)
+{
+ struct wpabuf *buf;
+ int ret = 0;
+ int res;
+ u16 info_ids[] = {
+ ANQP_CAPABILITY_LIST,
+ ANQP_VENUE_NAME,
+ ANQP_NETWORK_AUTH_TYPE,
+ ANQP_ROAMING_CONSORTIUM,
+ ANQP_IP_ADDR_TYPE_AVAILABILITY,
+ ANQP_NAI_REALM,
+ ANQP_3GPP_CELLULAR_NETWORK,
+ ANQP_DOMAIN_NAME
+ };
+ struct wpabuf *extra = NULL;
+
+ wpa_printf(MSG_DEBUG, "Interworking: ANQP Query Request to " MACSTR,
+ MAC2STR(bss->bssid));
+
+ buf = anqp_build_req(info_ids, sizeof(info_ids) / sizeof(info_ids[0]),
+ extra);
+ wpabuf_free(extra);
+ if (buf == NULL)
+ return -1;
+
+ res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, buf,
+ interworking_anqp_resp_cb, wpa_s);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request");
+ ret = -1;
+ } else
+ wpa_printf(MSG_DEBUG, "ANQP: Query started with dialog token "
+ "%u", res);
+
+ wpabuf_free(buf);
+ return ret;
+}
+
+
+struct nai_realm_eap {
+ u8 method;
+ u8 inner_method;
+ enum nai_realm_eap_auth_inner_non_eap inner_non_eap;
+ u8 cred_type;
+ u8 tunneled_cred_type;
+};
+
+struct nai_realm {
+ u8 encoding;
+ char *realm;
+ u8 eap_count;
+ struct nai_realm_eap *eap;
+};
+
+
+static void nai_realm_free(struct nai_realm *realms, u16 count)
+{
+ u16 i;
+
+ if (realms == NULL)
+ return;
+ for (i = 0; i < count; i++) {
+ os_free(realms[i].eap);
+ os_free(realms[i].realm);
+ }
+ os_free(realms);
+}
+
+
+static const u8 * nai_realm_parse_eap(struct nai_realm_eap *e, const u8 *pos,
+ const u8 *end)
+{
+ u8 elen, auth_count, a;
+ const u8 *e_end;
+
+ if (pos + 3 > end) {
+ wpa_printf(MSG_DEBUG, "No room for EAP Method fixed fields");
+ return NULL;
+ }
+
+ elen = *pos++;
+ if (pos + elen > end || elen < 2) {
+ wpa_printf(MSG_DEBUG, "No room for EAP Method subfield");
+ return NULL;
+ }
+ e_end = pos + elen;
+ e->method = *pos++;
+ auth_count = *pos++;
+ wpa_printf(MSG_DEBUG, "EAP Method: len=%u method=%u auth_count=%u",
+ elen, e->method, auth_count);
+
+ for (a = 0; a < auth_count; a++) {
+ u8 id, len;
+
+ if (pos + 2 > end || pos + 2 + pos[1] > end) {
+ wpa_printf(MSG_DEBUG, "No room for Authentication "
+ "Parameter subfield");
+ return NULL;
+ }
+
+ id = *pos++;
+ len = *pos++;
+
+ switch (id) {
+ case NAI_REALM_EAP_AUTH_NON_EAP_INNER_AUTH:
+ if (len < 1)
+ break;
+ e->inner_non_eap = *pos;
+ if (e->method != EAP_TYPE_TTLS)
+ break;
+ switch (*pos) {
+ case NAI_REALM_INNER_NON_EAP_PAP:
+ wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP");
+ break;
+ case NAI_REALM_INNER_NON_EAP_CHAP:
+ wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP");
+ break;
+ case NAI_REALM_INNER_NON_EAP_MSCHAP:
+ wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP");
+ break;
+ case NAI_REALM_INNER_NON_EAP_MSCHAPV2:
+ wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2");
+ break;
+ }
+ break;
+ case NAI_REALM_EAP_AUTH_INNER_AUTH_EAP_METHOD:
+ if (len < 1)
+ break;
+ e->inner_method = *pos;
+ wpa_printf(MSG_DEBUG, "Inner EAP method: %u",
+ e->inner_method);
+ break;
+ case NAI_REALM_EAP_AUTH_CRED_TYPE:
+ if (len < 1)
+ break;
+ e->cred_type = *pos;
+ wpa_printf(MSG_DEBUG, "Credential Type: %u",
+ e->cred_type);
+ break;
+ case NAI_REALM_EAP_AUTH_TUNNELED_CRED_TYPE:
+ if (len < 1)
+ break;
+ e->tunneled_cred_type = *pos;
+ wpa_printf(MSG_DEBUG, "Tunneled EAP Method Credential "
+ "Type: %u", e->tunneled_cred_type);
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "Unsupported Authentication "
+ "Parameter: id=%u len=%u", id, len);
+ wpa_hexdump(MSG_DEBUG, "Authentication Parameter "
+ "Value", pos, len);
+ break;
+ }
+
+ pos += len;
+ }
+
+ return e_end;
+}
+
+
+static const u8 * nai_realm_parse_realm(struct nai_realm *r, const u8 *pos,
+ const u8 *end)
+{
+ u16 len;
+ const u8 *f_end;
+ u8 realm_len, e;
+
+ if (end - pos < 4) {
+ wpa_printf(MSG_DEBUG, "No room for NAI Realm Data "
+ "fixed fields");
+ return NULL;
+ }
+
+ len = WPA_GET_LE16(pos); /* NAI Realm Data field Length */
+ pos += 2;
+ if (pos + len > end || len < 3) {
+ wpa_printf(MSG_DEBUG, "No room for NAI Realm Data "
+ "(len=%u; left=%u)",
+ len, (unsigned int) (end - pos));
+ return NULL;
+ }
+ f_end = pos + len;
+
+ r->encoding = *pos++;
+ realm_len = *pos++;
+ if (pos + realm_len > f_end) {
+ wpa_printf(MSG_DEBUG, "No room for NAI Realm "
+ "(len=%u; left=%u)",
+ realm_len, (unsigned int) (f_end - pos));
+ return NULL;
+ }
+ wpa_hexdump_ascii(MSG_DEBUG, "NAI Realm", pos, realm_len);
+ r->realm = os_malloc(realm_len + 1);
+ if (r->realm == NULL)
+ return NULL;
+ os_memcpy(r->realm, pos, realm_len);
+ r->realm[realm_len] = '\0';
+ pos += realm_len;
+
+ if (pos + 1 > f_end) {
+ wpa_printf(MSG_DEBUG, "No room for EAP Method Count");
+ return NULL;
+ }
+ r->eap_count = *pos++;
+ wpa_printf(MSG_DEBUG, "EAP Count: %u", r->eap_count);
+ if (pos + r->eap_count * 3 > f_end) {
+ wpa_printf(MSG_DEBUG, "No room for EAP Methods");
+ return NULL;
+ }
+ r->eap = os_zalloc(r->eap_count * sizeof(struct nai_realm_eap));
+ if (r->eap == NULL)
+ return NULL;
+
+ for (e = 0; e < r->eap_count; e++) {
+ pos = nai_realm_parse_eap(&r->eap[e], pos, f_end);
+ if (pos == NULL)
+ return NULL;
+ }
+
+ return f_end;
+}
+
+
+static struct nai_realm * nai_realm_parse(struct wpabuf *anqp, u16 *count)
+{
+ struct nai_realm *realm;
+ const u8 *pos, *end;
+ u16 i, num;
+
+ if (anqp == NULL || wpabuf_len(anqp) < 2)
+ return NULL;
+
+ pos = wpabuf_head_u8(anqp);
+ end = pos + wpabuf_len(anqp);
+ num = WPA_GET_LE16(pos);
+ wpa_printf(MSG_DEBUG, "NAI Realm Count: %u", num);
+ pos += 2;
+
+ if (num * 5 > end - pos) {
+ wpa_printf(MSG_DEBUG, "Invalid NAI Realm Count %u - not "
+ "enough data (%u octets) for that many realms",
+ num, (unsigned int) (end - pos));
+ return NULL;
+ }
+
+ realm = os_zalloc(num * sizeof(struct nai_realm));
+ if (realm == NULL)
+ return NULL;
+
+ for (i = 0; i < num; i++) {
+ pos = nai_realm_parse_realm(&realm[i], pos, end);
+ if (pos == NULL) {
+ nai_realm_free(realm, num);
+ return NULL;
+ }
+ }
+
+ *count = num;
+ return realm;
+}
+
+
+static int nai_realm_match(struct nai_realm *realm, const char *home_realm)
+{
+ char *tmp, *pos, *end;
+ int match = 0;
+
+ if (realm->realm == NULL || home_realm == NULL)
+ return 0;
+
+ if (os_strchr(realm->realm, ';') == NULL)
+ return os_strcasecmp(realm->realm, home_realm) == 0;
+
+ tmp = os_strdup(realm->realm);
+ if (tmp == NULL)
+ return 0;
+
+ pos = tmp;
+ while (*pos) {
+ end = os_strchr(pos, ';');
+ if (end)
+ *end = '\0';
+ if (os_strcasecmp(pos, home_realm) == 0) {
+ match = 1;
+ break;
+ }
+ if (end == NULL)
+ break;
+ pos = end + 1;
+ }
+
+ os_free(tmp);
+
+ return match;
+}
+
+
+static int nai_realm_cred_username(struct nai_realm_eap *eap)
+{
+ if (eap_get_name(EAP_VENDOR_IETF, eap->method) == NULL)
+ return 0; /* method not supported */
+
+ if (eap->method != EAP_TYPE_TTLS && eap->method != EAP_TYPE_PEAP) {
+ /* Only tunneled methods with username/password supported */
+ return 0;
+ }
+
+ if (eap->method == EAP_TYPE_PEAP &&
+ eap_get_name(EAP_VENDOR_IETF, eap->inner_method) == NULL)
+ return 0;
+
+ if (eap->method == EAP_TYPE_TTLS) {
+ if (eap->inner_method == 0 && eap->inner_non_eap == 0)
+ return 0;
+ if (eap->inner_method &&
+ eap_get_name(EAP_VENDOR_IETF, eap->inner_method) == NULL)
+ return 0;
+ if (eap->inner_non_eap &&
+ eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_PAP &&
+ eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_CHAP &&
+ eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_MSCHAP &&
+ eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_MSCHAPV2)
+ return 0;
+ }
+
+ if (eap->inner_method &&
+ eap->inner_method != EAP_TYPE_GTC &&
+ eap->inner_method != EAP_TYPE_MSCHAPV2)
+ return 0;
+
+ return 1;
+}
+
+
+static struct nai_realm_eap * nai_realm_find_eap(struct wpa_supplicant *wpa_s,
+ struct nai_realm *realm)
+{
+ u8 e;
+
+ if (wpa_s->conf->home_username == NULL ||
+ wpa_s->conf->home_username[0] == '\0' ||
+ wpa_s->conf->home_password == NULL ||
+ wpa_s->conf->home_password[0] == '\0')
+ return NULL;
+
+ for (e = 0; e < realm->eap_count; e++) {
+ struct nai_realm_eap *eap = &realm->eap[e];
+ if (nai_realm_cred_username(eap))
+ return eap;
+ }
+
+ return NULL;
+}
+
+
+#ifdef INTERWORKING_3GPP
+
+static int plmn_id_match(struct wpabuf *anqp, const char *imsi)
+{
+ const char *sep;
+ u8 plmn[3];
+ const u8 *pos, *end;
+ u8 udhl;
+
+ sep = os_strchr(imsi, '-');
+ if (sep == NULL || (sep - imsi != 5 && sep - imsi != 6))
+ return 0;
+
+ /* See Annex A of 3GPP TS 24.234 v8.1.0 for description */
+ plmn[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
+ plmn[1] = imsi[2] - '0';
+ if (sep - imsi == 6)
+ plmn[1] |= (imsi[5] - '0') << 4;
+ else
+ plmn[1] |= 0xf0;
+ plmn[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
+
+ if (anqp == NULL)
+ return 0;
+ pos = wpabuf_head_u8(anqp);
+ end = pos + wpabuf_len(anqp);
+ if (pos + 2 > end)
+ return 0;
+ if (*pos != 0) {
+ wpa_printf(MSG_DEBUG, "Unsupported GUD version 0x%x", *pos);
+ return 0;
+ }
+ pos++;
+ udhl = *pos++;
+ if (pos + udhl > end) {
+ wpa_printf(MSG_DEBUG, "Invalid UDHL");
+ return 0;
+ }
+ end = pos + udhl;
+
+ while (pos + 2 <= end) {
+ u8 iei, len;
+ const u8 *l_end;
+ iei = *pos++;
+ len = *pos++ & 0x7f;
+ if (pos + len > end)
+ break;
+ l_end = pos + len;
+
+ if (iei == 0 && len > 0) {
+ /* PLMN List */
+ u8 num, i;
+ num = *pos++;
+ for (i = 0; i < num; i++) {
+ if (pos + 3 > end)
+ break;
+ if (os_memcmp(pos, plmn, 3) == 0)
+ return 1; /* Found matching PLMN */
+ }
+ }
+
+ pos = l_end;
+ }
+
+ return 0;
+}
+
+
+static int set_root_nai(struct wpa_ssid *ssid, const char *imsi, char prefix)
+{
+ const char *sep, *msin;
+ char nai[100], *end, *pos;
+ size_t msin_len, plmn_len;
+
+ /*
+ * TS 23.003, Clause 14 (3GPP to WLAN Interworking)
+ * Root NAI:
+ * <aka:0|sim:1><IMSI>@wlan.mnc<MNC>.mcc<MCC>.3gppnetwork.org
+ * <MNC> is zero-padded to three digits in case two-digit MNC is used
+ */
+
+ if (imsi == NULL || os_strlen(imsi) > 16) {
+ wpa_printf(MSG_DEBUG, "No valid IMSI available");
+ return -1;
+ }
+ sep = os_strchr(imsi, '-');
+ if (sep == NULL)
+ return -1;
+ plmn_len = sep - imsi;
+ if (plmn_len != 5 && plmn_len != 6)
+ return -1;
+ msin = sep + 1;
+ msin_len = os_strlen(msin);
+
+ pos = nai;
+ end = pos + sizeof(nai);
+ *pos++ = prefix;
+ os_memcpy(pos, imsi, plmn_len);
+ pos += plmn_len;
+ os_memcpy(pos, msin, msin_len);
+ pos += msin_len;
+ pos += os_snprintf(pos, end - pos, "@wlan.mnc");
+ if (plmn_len == 5) {
+ *pos++ = '0';
+ *pos++ = imsi[3];
+ *pos++ = imsi[4];
+ } else {
+ *pos++ = imsi[3];
+ *pos++ = imsi[4];
+ *pos++ = imsi[5];
+ }
+ pos += os_snprintf(pos, end - pos, ".mcc%c%c%c.3gppnetwork.org",
+ imsi[0], imsi[1], imsi[2]);
+
+ return wpa_config_set_quoted(ssid, "identity", nai);
+}
+
+#endif /* INTERWORKING_3GPP */
+
+
+static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss)
+{
+#ifdef INTERWORKING_3GPP
+ struct wpa_ssid *ssid;
+ const u8 *ie;
+
+ ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
+ if (ie == NULL)
+ return -1;
+ wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR " (3GPP)",
+ MAC2STR(bss->bssid));
+
+ ssid = wpa_config_add_network(wpa_s->conf);
+ if (ssid == NULL)
+ return -1;
+
+ wpas_notify_network_added(wpa_s, ssid);
+ wpa_config_set_network_defaults(ssid);
+ ssid->temporary = 1;
+ ssid->ssid = os_zalloc(ie[1] + 1);
+ if (ssid->ssid == NULL)
+ goto fail;
+ os_memcpy(ssid->ssid, ie + 2, ie[1]);
+ ssid->ssid_len = ie[1];
+
+ /* TODO: figure out whether to use EAP-SIM, EAP-AKA, or EAP-AKA' */
+ if (wpa_config_set(ssid, "eap", "SIM", 0) < 0) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM not supported");
+ goto fail;
+ }
+ if (set_root_nai(ssid, wpa_s->conf->home_imsi, '1') < 0) {
+ wpa_printf(MSG_DEBUG, "Failed to set Root NAI");
+ goto fail;
+ }
+
+ if (wpa_s->conf->home_milenage && wpa_s->conf->home_milenage[0]) {
+ if (wpa_config_set_quoted(ssid, "password",
+ wpa_s->conf->home_milenage) < 0)
+ goto fail;
+ } else {
+ /* TODO: PIN */
+ if (wpa_config_set_quoted(ssid, "pcsc", "") < 0)
+ goto fail;
+ }
+
+ if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
+ wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
+ < 0)
+ goto fail;
+
+ wpa_supplicant_select_network(wpa_s, ssid);
+
+ return 0;
+
+fail:
+ wpas_notify_network_removed(wpa_s, ssid);
+ wpa_config_remove_network(wpa_s->conf, ssid->id);
+#endif /* INTERWORKING_3GPP */
+ return -1;
+}
+
+
+int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+{
+ struct wpa_ssid *ssid;
+ struct nai_realm *realm;
+ struct nai_realm_eap *eap = NULL;
+ u16 count, i;
+ char buf[100];
+ const u8 *ie;
+
+ if (bss == NULL)
+ return -1;
+ ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
+ if (ie == NULL || ie[1] == 0) {
+ wpa_printf(MSG_DEBUG, "Interworking: No SSID known for "
+ MACSTR, MAC2STR(bss->bssid));
+ return -1;
+ }
+
+ realm = nai_realm_parse(bss->anqp_nai_realm, &count);
+ if (realm == NULL) {
+ wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI "
+ "Realm list from " MACSTR, MAC2STR(bss->bssid));
+ count = 0;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (!nai_realm_match(&realm[i], wpa_s->conf->home_realm))
+ continue;
+ eap = nai_realm_find_eap(wpa_s, &realm[i]);
+ if (eap)
+ break;
+ }
+
+ if (!eap) {
+ if (interworking_connect_3gpp(wpa_s, bss) == 0) {
+ if (realm)
+ nai_realm_free(realm, count);
+ return 0;
+ }
+
+ wpa_printf(MSG_DEBUG, "Interworking: No matching credentials "
+ "and EAP method found for " MACSTR,
+ MAC2STR(bss->bssid));
+ nai_realm_free(realm, count);
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR,
+ MAC2STR(bss->bssid));
+
+ ssid = wpa_config_add_network(wpa_s->conf);
+ if (ssid == NULL) {
+ nai_realm_free(realm, count);
+ return -1;
+ }
+ wpas_notify_network_added(wpa_s, ssid);
+ wpa_config_set_network_defaults(ssid);
+ ssid->temporary = 1;
+ ssid->ssid = os_zalloc(ie[1] + 1);
+ if (ssid->ssid == NULL)
+ goto fail;
+ os_memcpy(ssid->ssid, ie + 2, ie[1]);
+ ssid->ssid_len = ie[1];
+
+ if (wpa_config_set(ssid, "eap", eap_get_name(EAP_VENDOR_IETF,
+ eap->method), 0) < 0)
+ goto fail;
+
+ if (wpa_s->conf->home_username && wpa_s->conf->home_username[0] &&
+ wpa_config_set_quoted(ssid, "identity",
+ wpa_s->conf->home_username) < 0)
+ goto fail;
+
+ if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
+ wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
+ < 0)
+ goto fail;
+
+ switch (eap->method) {
+ case EAP_TYPE_TTLS:
+ if (eap->inner_method) {
+ os_snprintf(buf, sizeof(buf), "\"autheap=%s\"",
+ eap_get_name(EAP_VENDOR_IETF,
+ eap->inner_method));
+ if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
+ goto fail;
+ break;
+ }
+ switch (eap->inner_non_eap) {
+ case NAI_REALM_INNER_NON_EAP_PAP:
+ if (wpa_config_set(ssid, "phase2", "\"auth=PAP\"", 0) <
+ 0)
+ goto fail;
+ break;
+ case NAI_REALM_INNER_NON_EAP_CHAP:
+ if (wpa_config_set(ssid, "phase2", "\"auth=CHAP\"", 0)
+ < 0)
+ goto fail;
+ break;
+ case NAI_REALM_INNER_NON_EAP_MSCHAP:
+ if (wpa_config_set(ssid, "phase2", "\"auth=CHAP\"", 0)
+ < 0)
+ goto fail;
+ break;
+ case NAI_REALM_INNER_NON_EAP_MSCHAPV2:
+ if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAPV2\"",
+ 0) < 0)
+ goto fail;
+ break;
+ }
+ break;
+ case EAP_TYPE_PEAP:
+ os_snprintf(buf, sizeof(buf), "\"auth=%s\"",
+ eap_get_name(EAP_VENDOR_IETF, eap->inner_method));
+ if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
+ goto fail;
+ break;
+ }
+
+ if (wpa_s->conf->home_ca_cert && wpa_s->conf->home_ca_cert[0] &&
+ wpa_config_set_quoted(ssid, "ca_cert", wpa_s->conf->home_ca_cert) <
+ 0)
+ goto fail;
+
+ nai_realm_free(realm, count);
+
+ wpa_supplicant_select_network(wpa_s, ssid);
+
+ return 0;
+
+fail:
+ wpas_notify_network_removed(wpa_s, ssid);
+ wpa_config_remove_network(wpa_s->conf, ssid->id);
+ nai_realm_free(realm, count);
+ return -1;
+}
+
+
+static int interworking_credentials_available_3gpp(
+ struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+{
+ int ret = 0;
+
+#ifdef INTERWORKING_3GPP
+ if (bss->anqp_3gpp == NULL)
+ return ret;
+
+ if (wpa_s->conf->home_imsi == NULL || !wpa_s->conf->home_imsi[0] ||
+ wpa_s->conf->home_milenage == NULL ||
+ !wpa_s->conf->home_milenage[0])
+ return ret;
+
+ wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from " MACSTR,
+ MAC2STR(bss->bssid));
+ ret = plmn_id_match(bss->anqp_3gpp, wpa_s->conf->home_imsi);
+ wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
+#endif /* INTERWORKING_3GPP */
+ return ret;
+}
+
+
+static int interworking_credentials_available_realm(
+ struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+{
+ struct nai_realm *realm;
+ u16 count, i;
+ int found = 0;
+
+ if (bss->anqp_nai_realm == NULL)
+ return 0;
+
+ if (wpa_s->conf->home_realm == NULL)
+ return 0;
+
+ wpa_printf(MSG_DEBUG, "Interworking: Parsing NAI Realm list from "
+ MACSTR, MAC2STR(bss->bssid));
+ realm = nai_realm_parse(bss->anqp_nai_realm, &count);
+ if (realm == NULL) {
+ wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI "
+ "Realm list from " MACSTR, MAC2STR(bss->bssid));
+ return 0;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (!nai_realm_match(&realm[i], wpa_s->conf->home_realm))
+ continue;
+ if (nai_realm_find_eap(wpa_s, &realm[i])) {
+ found++;
+ break;
+ }
+ }
+
+ nai_realm_free(realm, count);
+
+ return found;
+}
+
+
+static int interworking_credentials_available(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss)
+{
+ return interworking_credentials_available_realm(wpa_s, bss) ||
+ interworking_credentials_available_3gpp(wpa_s, bss);
+}
+
+
+static void interworking_select_network(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_bss *bss, *selected = NULL;
+ unsigned int count = 0;
+
+ wpa_s->network_select = 0;
+
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+ if (!interworking_credentials_available(wpa_s, bss))
+ continue;
+ count++;
+ wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR,
+ MAC2STR(bss->bssid));
+ if (selected == NULL && wpa_s->auto_select)
+ selected = bss;
+ }
+
+ if (count == 0) {
+ wpa_msg(wpa_s, MSG_INFO, INTERWORKING_NO_MATCH "No network "
+ "with matching credentials found");
+ }
+
+ if (selected)
+ interworking_connect(wpa_s, selected);
+}
+
+
+static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_bss *bss;
+ int found = 0;
+ const u8 *ie;
+
+ if (!wpa_s->fetch_anqp_in_progress)
+ return;
+
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+ if (!(bss->caps & IEEE80211_CAP_ESS))
+ continue;
+ ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB);
+ if (ie == NULL || ie[1] < 4 || !(ie[5] & 0x80))
+ continue; /* AP does not support Interworking */
+
+ if (!(bss->flags & WPA_BSS_ANQP_FETCH_TRIED)) {
+ found++;
+ bss->flags |= WPA_BSS_ANQP_FETCH_TRIED;
+ wpa_msg(wpa_s, MSG_INFO, "Starting ANQP fetch for "
+ MACSTR, MAC2STR(bss->bssid));
+ interworking_anqp_send_req(wpa_s, bss);
+ break;
+ }
+ }
+
+ if (found == 0) {
+ wpa_msg(wpa_s, MSG_INFO, "ANQP fetch completed");
+ wpa_s->fetch_anqp_in_progress = 0;
+ if (wpa_s->network_select)
+ interworking_select_network(wpa_s);
+ }
+}
+
+
+static void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_bss *bss;
+
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list)
+ bss->flags &= ~WPA_BSS_ANQP_FETCH_TRIED;
+
+ wpa_s->fetch_anqp_in_progress = 1;
+ interworking_next_anqp_fetch(wpa_s);
+}
+
+
+int interworking_fetch_anqp(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->fetch_anqp_in_progress || wpa_s->network_select)
+ return 0;
+
+ wpa_s->network_select = 0;
+
+ interworking_start_fetch_anqp(wpa_s);
+
+ return 0;
+}
+
+
+void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s->fetch_anqp_in_progress)
+ return;
+
+ wpa_s->fetch_anqp_in_progress = 0;
+}
+
+
+int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
+ u16 info_ids[], size_t num_ids)
+{
+ struct wpabuf *buf;
+ int ret = 0;
+ int freq;
+ struct wpa_bss *bss;
+ int res;
+
+ freq = wpa_s->assoc_freq;
+ bss = wpa_bss_get_bssid(wpa_s, dst);
+ if (bss)
+ freq = bss->freq;
+ if (freq <= 0)
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "ANQP: Query Request to " MACSTR " for %u id(s)",
+ MAC2STR(dst), (unsigned int) num_ids);
+
+ buf = anqp_build_req(info_ids, num_ids, NULL);
+ if (buf == NULL)
+ return -1;
+
+ res = gas_query_req(wpa_s->gas, dst, freq, buf, anqp_resp_cb, wpa_s);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request");
+ ret = -1;
+ } else
+ wpa_printf(MSG_DEBUG, "ANQP: Query started with dialog token "
+ "%u", res);
+
+ wpabuf_free(buf);
+ return ret;
+}
+
+
+static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
+ const u8 *sa, u16 info_id,
+ const u8 *data, size_t slen)
+{
+ const u8 *pos = data;
+ struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa);
+
+ switch (info_id) {
+ case ANQP_CAPABILITY_LIST:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " ANQP Capability list", MAC2STR(sa));
+ break;
+ case ANQP_VENUE_NAME:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " Venue Name", MAC2STR(sa));
+ wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Venue Name", pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_venue_name);
+ bss->anqp_venue_name = wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_NETWORK_AUTH_TYPE:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " Network Authentication Type information",
+ MAC2STR(sa));
+ wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Network Authentication "
+ "Type", pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_network_auth_type);
+ bss->anqp_network_auth_type =
+ wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_ROAMING_CONSORTIUM:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " Roaming Consortium list", MAC2STR(sa));
+ wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Roaming Consortium",
+ pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_roaming_consortium);
+ bss->anqp_roaming_consortium =
+ wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_IP_ADDR_TYPE_AVAILABILITY:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " IP Address Type Availability information",
+ MAC2STR(sa));
+ wpa_hexdump(MSG_MSGDUMP, "ANQP: IP Address Availability",
+ pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_ip_addr_type_availability);
+ bss->anqp_ip_addr_type_availability =
+ wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_NAI_REALM:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " NAI Realm list", MAC2STR(sa));
+ wpa_hexdump_ascii(MSG_DEBUG, "ANQP: NAI Realm", pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_nai_realm);
+ bss->anqp_nai_realm = wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_3GPP_CELLULAR_NETWORK:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " 3GPP Cellular Network information", MAC2STR(sa));
+ wpa_hexdump_ascii(MSG_DEBUG, "ANQP: 3GPP Cellular Network",
+ pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_3gpp);
+ bss->anqp_3gpp = wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_DOMAIN_NAME:
+ wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
+ " Domain Name list", MAC2STR(sa));
+ wpa_hexdump_ascii(MSG_MSGDUMP, "ANQP: Domain Name", pos, slen);
+ if (bss) {
+ wpabuf_free(bss->anqp_domain_name);
+ bss->anqp_domain_name = wpabuf_alloc_copy(pos, slen);
+ }
+ break;
+ case ANQP_VENDOR_SPECIFIC:
+ if (slen < 3)
+ return;
+
+ switch (WPA_GET_BE24(pos)) {
+ default:
+ wpa_printf(MSG_DEBUG, "Interworking: Unsupported "
+ "vendor-specific ANQP OUI %06x",
+ WPA_GET_BE24(pos));
+ return;
+ }
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "Interworking: Unsupported ANQP Info ID "
+ "%u", info_id);
+ break;
+ }
+}
+
+
+void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
+ enum gas_query_result result,
+ const struct wpabuf *adv_proto,
+ const struct wpabuf *resp, u16 status_code)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ const u8 *pos;
+ const u8 *end;
+ u16 info_id;
+ u16 slen;
+
+ if (result != GAS_QUERY_SUCCESS)
+ return;
+
+ pos = wpabuf_head(adv_proto);
+ if (wpabuf_len(adv_proto) < 4 || pos[0] != WLAN_EID_ADV_PROTO ||
+ pos[1] < 2 || pos[3] != ACCESS_NETWORK_QUERY_PROTOCOL) {
+ wpa_printf(MSG_DEBUG, "ANQP: Unexpected Advertisement "
+ "Protocol in response");
+ return;
+ }
+
+ pos = wpabuf_head(resp);
+ end = pos + wpabuf_len(resp);
+
+ while (pos < end) {
+ if (pos + 4 > end) {
+ wpa_printf(MSG_DEBUG, "ANQP: Invalid element");
+ break;
+ }
+ info_id = WPA_GET_LE16(pos);
+ pos += 2;
+ slen = WPA_GET_LE16(pos);
+ pos += 2;
+ if (pos + slen > end) {
+ wpa_printf(MSG_DEBUG, "ANQP: Invalid element length "
+ "for Info ID %u", info_id);
+ break;
+ }
+ interworking_parse_rx_anqp_resp(wpa_s, dst, info_id, pos,
+ slen);
+ pos += slen;
+ }
+}
+
+
+static void interworking_scan_res_handler(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_results *scan_res)
+{
+ wpa_printf(MSG_DEBUG, "Interworking: Scan results available - start "
+ "ANQP fetch");
+ interworking_start_fetch_anqp(wpa_s);
+}
+
+
+int interworking_select(struct wpa_supplicant *wpa_s, int auto_select)
+{
+ interworking_stop_fetch_anqp(wpa_s);
+ wpa_s->network_select = 1;
+ wpa_s->auto_select = !!auto_select;
+ wpa_printf(MSG_DEBUG, "Interworking: Start scan for network "
+ "selection");
+ wpa_s->scan_res_handler = interworking_scan_res_handler;
+ wpa_s->scan_req = 2;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+
+ return 0;
+}
diff --git a/wpa_supplicant/interworking.h b/wpa_supplicant/interworking.h
new file mode 100644
index 0000000..247df30
--- /dev/null
+++ b/wpa_supplicant/interworking.h
@@ -0,0 +1,31 @@
+/*
+ * Interworking (IEEE 802.11u)
+ * Copyright (c) 2011, Qualcomm Atheros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef INTERWORKING_H
+#define INTERWORKING_H
+
+enum gas_query_result;
+
+int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
+ u16 info_ids[], size_t num_ids);
+void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
+ enum gas_query_result result,
+ const struct wpabuf *adv_proto,
+ const struct wpabuf *resp, u16 status_code);
+int interworking_fetch_anqp(struct wpa_supplicant *wpa_s);
+void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s);
+int interworking_select(struct wpa_supplicant *wpa_s, int auto_select);
+int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
+
+#endif /* INTERWORKING_H */
diff --git a/wpa_supplicant/mlme.c b/wpa_supplicant/mlme.c
deleted file mode 100644
index 49713f5..0000000
--- a/wpa_supplicant/mlme.c
+++ /dev/null
@@ -1,3181 +0,0 @@
-/*
- * WPA Supplicant - Client mode MLME
- * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004, Instant802 Networks, Inc.
- * Copyright (c) 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "config_ssid.h"
-#include "wpa_supplicant_i.h"
-#include "notify.h"
-#include "driver_i.h"
-#include "rsn_supp/wpa.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "mlme.h"
-
-
-/* Timeouts and intervals in milliseconds */
-#define IEEE80211_AUTH_TIMEOUT (200)
-#define IEEE80211_AUTH_MAX_TRIES 3
-#define IEEE80211_ASSOC_TIMEOUT (200)
-#define IEEE80211_ASSOC_MAX_TRIES 3
-#define IEEE80211_MONITORING_INTERVAL (2000)
-#define IEEE80211_PROBE_INTERVAL (60000)
-#define IEEE80211_RETRY_AUTH_INTERVAL (1000)
-#define IEEE80211_SCAN_INTERVAL (2000)
-#define IEEE80211_SCAN_INTERVAL_SLOW (15000)
-#define IEEE80211_IBSS_JOIN_TIMEOUT (20000)
-
-#define IEEE80211_PROBE_DELAY (33)
-#define IEEE80211_CHANNEL_TIME (33)
-#define IEEE80211_PASSIVE_CHANNEL_TIME (200)
-#define IEEE80211_SCAN_RESULT_EXPIRE (10000)
-#define IEEE80211_IBSS_MERGE_INTERVAL (30000)
-#define IEEE80211_IBSS_INACTIVITY_LIMIT (60000)
-
-#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
-
-
-#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4))
-
-
-struct ieee80211_sta_bss {
- struct ieee80211_sta_bss *next;
- struct ieee80211_sta_bss *hnext;
-
- u8 bssid[ETH_ALEN];
- u8 ssid[MAX_SSID_LEN];
- size_t ssid_len;
- u16 capability; /* host byte order */
- int hw_mode;
- int channel;
- int freq;
- int rssi;
- u8 *ie;
- size_t ie_len;
- u8 *wpa_ie;
- size_t wpa_ie_len;
- u8 *rsn_ie;
- size_t rsn_ie_len;
- u8 *wmm_ie;
- size_t wmm_ie_len;
- u8 *mdie;
- size_t mdie_len;
-#define IEEE80211_MAX_SUPP_RATES 32
- u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
- size_t supp_rates_len;
- int beacon_int;
- u64 timestamp;
-
- int probe_resp;
- struct os_time last_update;
-};
-
-
-static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
- const u8 *dst,
- const u8 *ssid, size_t ssid_len);
-static struct ieee80211_sta_bss *
-ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid);
-static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s);
-static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s);
-static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx);
-static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx);
-static void ieee80211_build_tspec(struct wpabuf *buf);
-static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len);
-
-
-static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s,
- enum hostapd_hw_mode phymode, int chan,
- int freq)
-{
- size_t i;
- struct hostapd_hw_modes *mode;
-
- for (i = 0; i < wpa_s->mlme.num_modes; i++) {
- mode = &wpa_s->mlme.modes[i];
- if (mode->mode == phymode) {
- wpa_s->mlme.curr_rates = mode->rates;
- wpa_s->mlme.num_curr_rates = mode->num_rates;
- break;
- }
- }
-
- return wpa_drv_set_channel(wpa_s, phymode, chan, freq);
-}
-
-
-static int ecw2cw(int ecw)
-{
- int cw = 1;
- while (ecw > 0) {
- cw <<= 1;
- ecw--;
- }
- return cw - 1;
-}
-
-
-static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s,
- const u8 *wmm_param, size_t wmm_param_len)
-{
- size_t left;
- int count;
- const u8 *pos;
- u8 wmm_acm;
-
- if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
- return;
- count = wmm_param[6] & 0x0f;
- if (count == wpa_s->mlme.wmm_last_param_set)
- return;
- wpa_s->mlme.wmm_last_param_set = count;
-
- pos = wmm_param + 8;
- left = wmm_param_len - 8;
-
- wmm_acm = 0;
- for (; left >= 4; left -= 4, pos += 4) {
- int aci = (pos[0] >> 5) & 0x03;
- int acm = (pos[0] >> 4) & 0x01;
- int aifs, cw_max, cw_min, burst_time;
-
- switch (aci) {
- case 1: /* AC_BK */
- if (acm)
- wmm_acm |= BIT(1) | BIT(2); /* BK/- */
- break;
- case 2: /* AC_VI */
- if (acm)
- wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
- break;
- case 3: /* AC_VO */
- if (acm)
- wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
- break;
- case 0: /* AC_BE */
- default:
- if (acm)
- wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
- break;
- }
-
- aifs = pos[0] & 0x0f;
- cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
- cw_min = ecw2cw(pos[1] & 0x0f);
- /* TXOP is in units of 32 usec; burst_time in 0.1 ms */
- burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100;
- wpa_printf(MSG_DEBUG, "MLME: WMM aci=%d acm=%d aifs=%d "
- "cWmin=%d cWmax=%d burst=%d",
- aci, acm, aifs, cw_min, cw_max, burst_time);
- /* TODO: driver configuration */
- }
-}
-
-
-static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc)
-{
- if (wpa_s->mlme.associated == assoc && !assoc)
- return;
-
- wpa_s->mlme.associated = assoc;
-
- if (assoc) {
- union wpa_event_data data;
- os_memset(&data, 0, sizeof(data));
- wpa_s->mlme.prev_bssid_set = 1;
- os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN);
- data.assoc_info.req_ies = wpa_s->mlme.assocreq_ies;
- data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len;
- data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies;
- data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len;
- data.assoc_info.freq = wpa_s->mlme.freq;
- wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
- } else {
- wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL);
- }
- os_get_time(&wpa_s->mlme.last_probe);
-}
-
-
-static int ieee80211_sta_tx(struct wpa_supplicant *wpa_s, const u8 *buf,
- size_t len)
-{
- return wpa_drv_send_mlme(wpa_s, buf, len);
-}
-
-
-static void ieee80211_send_auth(struct wpa_supplicant *wpa_s,
- int transaction, const u8 *extra,
- size_t extra_len, int encrypt)
-{
- u8 *buf;
- size_t len;
- struct ieee80211_mgmt *mgmt;
-
- buf = os_malloc(sizeof(*mgmt) + 6 + extra_len);
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
- "auth frame");
- return;
- }
-
- mgmt = (struct ieee80211_mgmt *) buf;
- len = 24 + 6;
- os_memset(mgmt, 0, 24 + 6);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_AUTH);
- if (encrypt)
- mgmt->frame_control |= host_to_le16(WLAN_FC_ISWEP);
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->u.auth.auth_alg = host_to_le16(wpa_s->mlme.auth_alg);
- mgmt->u.auth.auth_transaction = host_to_le16(transaction);
- wpa_s->mlme.auth_transaction = transaction + 1;
- mgmt->u.auth.status_code = host_to_le16(0);
- if (extra) {
- os_memcpy(buf + len, extra, extra_len);
- len += extra_len;
- }
-
- ieee80211_sta_tx(wpa_s, buf, len);
- os_free(buf);
-}
-
-
-static void ieee80211_reschedule_timer(struct wpa_supplicant *wpa_s, int ms)
-{
- eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL);
- eloop_register_timeout(ms / 1000, 1000 * (ms % 1000),
- ieee80211_sta_timer, wpa_s, NULL);
-}
-
-
-static void ieee80211_authenticate(struct wpa_supplicant *wpa_s)
-{
- u8 *extra;
- size_t extra_len;
-
- wpa_s->mlme.auth_tries++;
- if (wpa_s->mlme.auth_tries > IEEE80211_AUTH_MAX_TRIES) {
- wpa_printf(MSG_DEBUG, "MLME: authentication with AP " MACSTR
- " timed out", MAC2STR(wpa_s->bssid));
- return;
- }
-
- wpa_s->mlme.state = IEEE80211_AUTHENTICATE;
- wpa_printf(MSG_DEBUG, "MLME: authenticate with AP " MACSTR,
- MAC2STR(wpa_s->bssid));
-
- extra = NULL;
- extra_len = 0;
-
-#ifdef CONFIG_IEEE80211R
- if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X ||
- wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) &&
- wpa_s->mlme.ft_ies) {
- struct ieee80211_sta_bss *bss;
- struct rsn_mdie *mdie = NULL;
- bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
- if (bss && bss->mdie_len >= 2 + sizeof(*mdie))
- mdie = (struct rsn_mdie *) (bss->mdie + 2);
- if (mdie &&
- os_memcmp(mdie->mobility_domain, wpa_s->mlme.current_md,
- MOBILITY_DOMAIN_ID_LEN) == 0) {
- wpa_printf(MSG_DEBUG, "MLME: Trying to use FT "
- "over-the-air");
- wpa_s->mlme.auth_alg = WLAN_AUTH_FT;
- extra = wpa_s->mlme.ft_ies;
- extra_len = wpa_s->mlme.ft_ies_len;
- }
- }
-#endif /* CONFIG_IEEE80211R */
-
- ieee80211_send_auth(wpa_s, 1, extra, extra_len, 0);
-
- ieee80211_reschedule_timer(wpa_s, IEEE80211_AUTH_TIMEOUT);
-}
-
-
-static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s)
-{
- struct ieee80211_mgmt *mgmt;
- u8 *pos, *ies, *buf;
- int i, len;
- u16 capab;
- struct ieee80211_sta_bss *bss;
- int wmm = 0;
- size_t blen, buflen;
-
- if (wpa_s->mlme.curr_rates == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: curr_rates not set for assoc");
- return;
- }
-
- buflen = sizeof(*mgmt) + 200 + wpa_s->mlme.extra_ie_len +
- wpa_s->mlme.ssid_len;
-#ifdef CONFIG_IEEE80211R
- if (wpa_s->mlme.ft_ies)
- buflen += wpa_s->mlme.ft_ies_len;
-#endif /* CONFIG_IEEE80211R */
- buf = os_malloc(buflen);
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
- "assoc frame");
- return;
- }
- blen = 0;
-
- capab = wpa_s->mlme.capab;
- if (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G) {
- capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
- WLAN_CAPABILITY_SHORT_PREAMBLE;
- }
- bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
- if (bss) {
- if (bss->capability & WLAN_CAPABILITY_PRIVACY)
- capab |= WLAN_CAPABILITY_PRIVACY;
- if (bss->wmm_ie) {
- wmm = 1;
- }
- }
-
- mgmt = (struct ieee80211_mgmt *) buf;
- blen += 24;
- os_memset(mgmt, 0, 24);
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
-
- if (wpa_s->mlme.prev_bssid_set) {
- blen += 10;
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_REASSOC_REQ);
- mgmt->u.reassoc_req.capab_info = host_to_le16(capab);
- mgmt->u.reassoc_req.listen_interval = host_to_le16(1);
- os_memcpy(mgmt->u.reassoc_req.current_ap,
- wpa_s->mlme.prev_bssid,
- ETH_ALEN);
- } else {
- blen += 4;
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_ASSOC_REQ);
- mgmt->u.assoc_req.capab_info = host_to_le16(capab);
- mgmt->u.assoc_req.listen_interval = host_to_le16(1);
- }
-
- /* SSID */
- ies = pos = buf + blen;
- blen += 2 + wpa_s->mlme.ssid_len;
- *pos++ = WLAN_EID_SSID;
- *pos++ = wpa_s->mlme.ssid_len;
- os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
-
- len = wpa_s->mlme.num_curr_rates;
- if (len > 8)
- len = 8;
- pos = buf + blen;
- blen += len + 2;
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos++ = len;
- for (i = 0; i < len; i++)
- *pos++ = (u8) (wpa_s->mlme.curr_rates[i] / 5);
-
- if (wpa_s->mlme.num_curr_rates > len) {
- pos = buf + blen;
- blen += wpa_s->mlme.num_curr_rates - len + 2;
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos++ = wpa_s->mlme.num_curr_rates - len;
- for (i = len; i < wpa_s->mlme.num_curr_rates; i++)
- *pos++ = (u8) (wpa_s->mlme.curr_rates[i] / 5);
- }
-
- if (wpa_s->mlme.extra_ie && wpa_s->mlme.auth_alg != WLAN_AUTH_FT) {
- pos = buf + blen;
- blen += wpa_s->mlme.extra_ie_len;
- os_memcpy(pos, wpa_s->mlme.extra_ie, wpa_s->mlme.extra_ie_len);
- }
-
-#ifdef CONFIG_IEEE80211R
- if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X ||
- wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) &&
- wpa_s->mlme.auth_alg != WLAN_AUTH_FT &&
- bss && bss->mdie &&
- bss->mdie_len >= 2 + sizeof(struct rsn_mdie) &&
- bss->mdie[1] >= sizeof(struct rsn_mdie)) {
- pos = buf + blen;
- blen += 2 + sizeof(struct rsn_mdie);
- *pos++ = WLAN_EID_MOBILITY_DOMAIN;
- *pos++ = sizeof(struct rsn_mdie);
- os_memcpy(pos, bss->mdie + 2, MOBILITY_DOMAIN_ID_LEN);
- pos += MOBILITY_DOMAIN_ID_LEN;
- *pos++ = 0; /* FIX: copy from the target AP's MDIE */
- }
-
- if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X ||
- wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) &&
- wpa_s->mlme.auth_alg == WLAN_AUTH_FT && wpa_s->mlme.ft_ies) {
- pos = buf + blen;
- os_memcpy(pos, wpa_s->mlme.ft_ies, wpa_s->mlme.ft_ies_len);
- pos += wpa_s->mlme.ft_ies_len;
- blen += wpa_s->mlme.ft_ies_len;
- }
-#endif /* CONFIG_IEEE80211R */
-
- if (wmm && wpa_s->mlme.wmm_enabled) {
- pos = buf + blen;
- blen += 9;
- *pos++ = WLAN_EID_VENDOR_SPECIFIC;
- *pos++ = 7; /* len */
- *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
- *pos++ = 0x50;
- *pos++ = 0xf2;
- *pos++ = 2; /* WMM */
- *pos++ = 0; /* WMM info */
- *pos++ = 1; /* WMM ver */
- *pos++ = 0;
- }
-
- os_free(wpa_s->mlme.assocreq_ies);
- wpa_s->mlme.assocreq_ies_len = (buf + blen) - ies;
- wpa_s->mlme.assocreq_ies = os_malloc(wpa_s->mlme.assocreq_ies_len);
- if (wpa_s->mlme.assocreq_ies) {
- os_memcpy(wpa_s->mlme.assocreq_ies, ies,
- wpa_s->mlme.assocreq_ies_len);
- }
-
- ieee80211_sta_tx(wpa_s, buf, blen);
- os_free(buf);
-}
-
-
-static void ieee80211_send_deauth(struct wpa_supplicant *wpa_s, u16 reason)
-{
- u8 *buf;
- size_t len;
- struct ieee80211_mgmt *mgmt;
-
- buf = os_zalloc(sizeof(*mgmt));
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
- "deauth frame");
- return;
- }
-
- mgmt = (struct ieee80211_mgmt *) buf;
- len = 24;
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_DEAUTH);
- len += 2;
- mgmt->u.deauth.reason_code = host_to_le16(reason);
-
- ieee80211_sta_tx(wpa_s, buf, len);
- os_free(buf);
-}
-
-
-static void ieee80211_send_disassoc(struct wpa_supplicant *wpa_s, u16 reason)
-{
- u8 *buf;
- size_t len;
- struct ieee80211_mgmt *mgmt;
-
- buf = os_zalloc(sizeof(*mgmt));
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
- "disassoc frame");
- return;
- }
-
- mgmt = (struct ieee80211_mgmt *) buf;
- len = 24;
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_DISASSOC);
- len += 2;
- mgmt->u.disassoc.reason_code = host_to_le16(reason);
-
- ieee80211_sta_tx(wpa_s, buf, len);
- os_free(buf);
-}
-
-
-static int ieee80211_privacy_mismatch(struct wpa_supplicant *wpa_s)
-{
- struct ieee80211_sta_bss *bss;
- int res = 0;
-
- if (wpa_s->mlme.mixed_cell ||
- wpa_s->mlme.key_mgmt != KEY_MGMT_NONE)
- return 0;
-
- bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
- if (bss == NULL)
- return 0;
-
- if (ieee80211_sta_wep_configured(wpa_s) !=
- !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
- res = 1;
-
- return res;
-}
-
-
-static void ieee80211_associate(struct wpa_supplicant *wpa_s)
-{
- wpa_s->mlme.assoc_tries++;
- if (wpa_s->mlme.assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
- wpa_printf(MSG_DEBUG, "MLME: association with AP " MACSTR
- " timed out", MAC2STR(wpa_s->bssid));
- return;
- }
-
- wpa_s->mlme.state = IEEE80211_ASSOCIATE;
- wpa_printf(MSG_DEBUG, "MLME: associate with AP " MACSTR,
- MAC2STR(wpa_s->bssid));
- if (ieee80211_privacy_mismatch(wpa_s)) {
- wpa_printf(MSG_DEBUG, "MLME: mismatch in privacy "
- "configuration and mixed-cell disabled - abort "
- "association");
- return;
- }
-
- ieee80211_send_assoc(wpa_s);
-
- ieee80211_reschedule_timer(wpa_s, IEEE80211_ASSOC_TIMEOUT);
-}
-
-
-static void ieee80211_associated(struct wpa_supplicant *wpa_s)
-{
- int disassoc;
-
- /* TODO: start monitoring current AP signal quality and number of
- * missed beacons. Scan other channels every now and then and search
- * for better APs. */
- /* TODO: remove expired BSSes */
-
- wpa_s->mlme.state = IEEE80211_ASSOCIATED;
-
-#if 0 /* FIX */
- sta = sta_info_get(local, wpa_s->bssid);
- if (sta == NULL) {
- wpa_printf(MSG_DEBUG "MLME: No STA entry for own AP " MACSTR,
- MAC2STR(wpa_s->bssid));
- disassoc = 1;
- } else {
- disassoc = 0;
- if (time_after(jiffies,
- sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
- if (wpa_s->mlme.probereq_poll) {
- wpa_printf(MSG_DEBUG "MLME: No ProbeResp from "
- "current AP " MACSTR " - assume "
- "out of range",
- MAC2STR(wpa_s->bssid));
- disassoc = 1;
- } else {
- ieee80211_send_probe_req(
- wpa_s->bssid,
- wpa_s->mlme.scan_ssid,
- wpa_s->mlme.scan_ssid_len);
- wpa_s->mlme.probereq_poll = 1;
- }
- } else {
- wpa_s->mlme.probereq_poll = 0;
- if (time_after(jiffies, wpa_s->mlme.last_probe +
- IEEE80211_PROBE_INTERVAL)) {
- wpa_s->mlme.last_probe = jiffies;
- ieee80211_send_probe_req(wpa_s->bssid,
- wpa_s->mlme.ssid,
- wpa_s->mlme.ssid_len);
- }
- }
- sta_info_release(local, sta);
- }
-#else
- disassoc = 0;
-#endif
- if (disassoc) {
- wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL);
- ieee80211_reschedule_timer(wpa_s,
- IEEE80211_MONITORING_INTERVAL +
- 30000);
- } else {
- ieee80211_reschedule_timer(wpa_s,
- IEEE80211_MONITORING_INTERVAL);
- }
-}
-
-
-static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
- const u8 *dst,
- const u8 *ssid, size_t ssid_len)
-{
- u8 *buf;
- size_t len;
- struct ieee80211_mgmt *mgmt;
- u8 *pos, *supp_rates;
- u8 *esupp_rates = NULL;
- int i;
-
- buf = os_malloc(sizeof(*mgmt) + 200 + wpa_s->mlme.extra_probe_ie_len);
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
- "probe request");
- return;
- }
-
- mgmt = (struct ieee80211_mgmt *) buf;
- len = 24;
- os_memset(mgmt, 0, 24);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_PROBE_REQ);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- if (dst) {
- os_memcpy(mgmt->da, dst, ETH_ALEN);
- os_memcpy(mgmt->bssid, dst, ETH_ALEN);
- } else {
- os_memset(mgmt->da, 0xff, ETH_ALEN);
- os_memset(mgmt->bssid, 0xff, ETH_ALEN);
- }
- pos = buf + len;
- len += 2 + ssid_len;
- *pos++ = WLAN_EID_SSID;
- *pos++ = ssid_len;
- os_memcpy(pos, ssid, ssid_len);
-
- supp_rates = buf + len;
- len += 2;
- supp_rates[0] = WLAN_EID_SUPP_RATES;
- supp_rates[1] = 0;
- for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) {
- if (esupp_rates) {
- pos = buf + len;
- len++;
- esupp_rates[1]++;
- } else if (supp_rates[1] == 8) {
- esupp_rates = pos;
- esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
- esupp_rates[1] = 1;
- pos = &esupp_rates[2];
- len += 3;
- } else {
- pos = buf + len;
- len++;
- supp_rates[1]++;
- }
- *pos++ = wpa_s->mlme.curr_rates[i] / 5;
- }
-
- if (wpa_s->mlme.extra_probe_ie) {
- os_memcpy(pos, wpa_s->mlme.extra_probe_ie,
- wpa_s->mlme.extra_probe_ie_len);
- len += wpa_s->mlme.extra_probe_ie_len;
- }
-
- ieee80211_sta_tx(wpa_s, buf, len);
- os_free(buf);
-}
-
-
-static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s)
-{
-#if 0 /* FIX */
- if (sdata == NULL || sdata->default_key == NULL ||
- sdata->default_key->alg != ALG_WEP)
- return 0;
- return 1;
-#else
- return 0;
-#endif
-}
-
-
-static void ieee80211_auth_completed(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "MLME: authenticated");
- wpa_s->mlme.authenticated = 1;
- ieee80211_associate(wpa_s);
-}
-
-
-static void ieee80211_auth_challenge(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- u8 *pos;
- struct ieee802_11_elems elems;
-
- wpa_printf(MSG_DEBUG, "MLME: replying to auth challenge");
- pos = mgmt->u.auth.variable;
- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems, 0)
- == ParseFailed) {
- wpa_printf(MSG_DEBUG, "MLME: failed to parse Auth(challenge)");
- return;
- }
- if (elems.challenge == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: no challenge IE in shared key "
- "auth frame");
- return;
- }
- ieee80211_send_auth(wpa_s, 3, elems.challenge - 2,
- elems.challenge_len + 2, 1);
-}
-
-
-static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- u16 auth_alg, auth_transaction, status_code;
- int adhoc;
-
- adhoc = ssid && ssid->mode == WPAS_MODE_IBSS;
-
- if (wpa_s->mlme.state != IEEE80211_AUTHENTICATE && !adhoc) {
- wpa_printf(MSG_DEBUG, "MLME: authentication frame received "
- "from " MACSTR ", but not in authenticate state - "
- "ignored", MAC2STR(mgmt->sa));
- return;
- }
-
- if (len < 24 + 6) {
- wpa_printf(MSG_DEBUG, "MLME: too short (%lu) authentication "
- "frame received from " MACSTR " - ignored",
- (unsigned long) len, MAC2STR(mgmt->sa));
- return;
- }
-
- if (!adhoc && os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: authentication frame received "
- "from unknown AP (SA=" MACSTR " BSSID=" MACSTR
- ") - ignored",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
- return;
- }
-
- if (adhoc && os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: authentication frame received "
- "from unknown BSSID (SA=" MACSTR " BSSID=" MACSTR
- ") - ignored",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
- return;
- }
-
- auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
- auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
- status_code = le_to_host16(mgmt->u.auth.status_code);
-
- wpa_printf(MSG_DEBUG, "MLME: RX authentication from " MACSTR
- " (alg=%d transaction=%d status=%d)",
- MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code);
-
- if (adhoc) {
- /* IEEE 802.11 standard does not require authentication in IBSS
- * networks and most implementations do not seem to use it.
- * However, try to reply to authentication attempts if someone
- * has actually implemented this.
- * TODO: Could implement shared key authentication. */
- if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) {
- wpa_printf(MSG_DEBUG, "MLME: unexpected IBSS "
- "authentication frame (alg=%d "
- "transaction=%d)",
- auth_alg, auth_transaction);
- return;
- }
- ieee80211_send_auth(wpa_s, 2, NULL, 0, 0);
- }
-
- if (auth_alg != wpa_s->mlme.auth_alg ||
- auth_transaction != wpa_s->mlme.auth_transaction) {
- wpa_printf(MSG_DEBUG, "MLME: unexpected authentication frame "
- "(alg=%d transaction=%d)",
- auth_alg, auth_transaction);
- return;
- }
-
- if (status_code != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "MLME: AP denied authentication "
- "(auth_alg=%d code=%d)", wpa_s->mlme.auth_alg,
- status_code);
- if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
- const int num_algs = 3;
- u8 algs[num_algs];
- int i, pos;
- algs[0] = algs[1] = algs[2] = 0xff;
- if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_OPEN)
- algs[0] = WLAN_AUTH_OPEN;
- if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_SHARED)
- algs[1] = WLAN_AUTH_SHARED_KEY;
- if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_LEAP)
- algs[2] = WLAN_AUTH_LEAP;
- if (wpa_s->mlme.auth_alg == WLAN_AUTH_OPEN)
- pos = 0;
- else if (wpa_s->mlme.auth_alg == WLAN_AUTH_SHARED_KEY)
- pos = 1;
- else
- pos = 2;
- for (i = 0; i < num_algs; i++) {
- pos++;
- if (pos >= num_algs)
- pos = 0;
- if (algs[pos] == wpa_s->mlme.auth_alg ||
- algs[pos] == 0xff)
- continue;
- if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
- !ieee80211_sta_wep_configured(wpa_s))
- continue;
- wpa_s->mlme.auth_alg = algs[pos];
- wpa_printf(MSG_DEBUG, "MLME: set auth_alg=%d "
- "for next try",
- wpa_s->mlme.auth_alg);
- break;
- }
- }
- return;
- }
-
- switch (wpa_s->mlme.auth_alg) {
- case WLAN_AUTH_OPEN:
- case WLAN_AUTH_LEAP:
- ieee80211_auth_completed(wpa_s);
- break;
- case WLAN_AUTH_SHARED_KEY:
- if (wpa_s->mlme.auth_transaction == 4)
- ieee80211_auth_completed(wpa_s);
- else
- ieee80211_auth_challenge(wpa_s, mgmt, len,
- rx_status);
- break;
-#ifdef CONFIG_IEEE80211R
- case WLAN_AUTH_FT:
- {
- union wpa_event_data data;
- struct wpabuf *ric = NULL;
- os_memset(&data, 0, sizeof(data));
- data.ft_ies.ies = mgmt->u.auth.variable;
- data.ft_ies.ies_len = len -
- (mgmt->u.auth.variable - (u8 *) mgmt);
- os_memcpy(data.ft_ies.target_ap, wpa_s->bssid, ETH_ALEN);
- if (os_strcmp(wpa_s->driver->name, "test") == 0 &&
- wpa_s->mlme.wmm_enabled) {
- ric = wpabuf_alloc(200);
- if (ric) {
- /* Build simple RIC-Request: RDIE | TSPEC */
-
- /* RIC Data (RDIE) */
- wpabuf_put_u8(ric, WLAN_EID_RIC_DATA);
- wpabuf_put_u8(ric, 4);
- wpabuf_put_u8(ric, 0); /* RDIE Identifier */
- wpabuf_put_u8(ric, 1); /* Resource Descriptor
- * Count */
- wpabuf_put_le16(ric, 0); /* Status Code */
-
- /* WMM TSPEC */
- ieee80211_build_tspec(ric);
-
- data.ft_ies.ric_ies = wpabuf_head(ric);
- data.ft_ies.ric_ies_len = wpabuf_len(ric);
- }
- }
-
- wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data);
- wpabuf_free(ric);
- ieee80211_auth_completed(wpa_s);
- break;
- }
-#endif /* CONFIG_IEEE80211R */
- }
-}
-
-
-static void ieee80211_rx_mgmt_deauth(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- u16 reason_code;
-
- if (len < 24 + 2) {
- wpa_printf(MSG_DEBUG, "MLME: too short (%lu) deauthentication "
- "frame received from " MACSTR " - ignored",
- (unsigned long) len, MAC2STR(mgmt->sa));
- return;
- }
-
- if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: deauthentication frame received "
- "from unknown AP (SA=" MACSTR " BSSID=" MACSTR
- ") - ignored",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
- return;
- }
-
- reason_code = le_to_host16(mgmt->u.deauth.reason_code);
-
- wpa_printf(MSG_DEBUG, "MLME: RX deauthentication from " MACSTR
- " (reason=%d)", MAC2STR(mgmt->sa), reason_code);
-
- if (wpa_s->mlme.authenticated)
- wpa_printf(MSG_DEBUG, "MLME: deauthenticated");
-
- if (wpa_s->mlme.state == IEEE80211_AUTHENTICATE ||
- wpa_s->mlme.state == IEEE80211_ASSOCIATE ||
- wpa_s->mlme.state == IEEE80211_ASSOCIATED) {
- wpa_s->mlme.state = IEEE80211_AUTHENTICATE;
- ieee80211_reschedule_timer(wpa_s,
- IEEE80211_RETRY_AUTH_INTERVAL);
- }
-
- ieee80211_set_associated(wpa_s, 0);
- wpa_s->mlme.authenticated = 0;
-}
-
-
-static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- u16 reason_code;
-
- if (len < 24 + 2) {
- wpa_printf(MSG_DEBUG, "MLME: too short (%lu) disassociation "
- "frame received from " MACSTR " - ignored",
- (unsigned long) len, MAC2STR(mgmt->sa));
- return;
- }
-
- if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: disassociation frame received "
- "from unknown AP (SA=" MACSTR " BSSID=" MACSTR
- ") - ignored",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
- return;
- }
-
- reason_code = le_to_host16(mgmt->u.disassoc.reason_code);
-
- wpa_printf(MSG_DEBUG, "MLME: RX disassociation from " MACSTR
- " (reason=%d)", MAC2STR(mgmt->sa), reason_code);
-
- if (wpa_s->mlme.associated)
- wpa_printf(MSG_DEBUG, "MLME: disassociated");
-
- if (wpa_s->mlme.state == IEEE80211_ASSOCIATED) {
- wpa_s->mlme.state = IEEE80211_ASSOCIATE;
- ieee80211_reschedule_timer(wpa_s,
- IEEE80211_RETRY_AUTH_INTERVAL);
- }
-
- ieee80211_set_associated(wpa_s, 0);
-}
-
-
-static void ieee80211_build_tspec(struct wpabuf *buf)
-{
- struct wmm_tspec_element *tspec;
- int tid, up;
-
- tspec = wpabuf_put(buf, sizeof(*tspec));
- tspec->eid = WLAN_EID_VENDOR_SPECIFIC;
- tspec->length = sizeof(*tspec) - 2;
- tspec->oui[0] = 0x00;
- tspec->oui[1] = 0x50;
- tspec->oui[2] = 0xf2;
- tspec->oui_type = 2;
- tspec->oui_subtype = 2;
- tspec->version = 1;
-
- tid = 1;
- up = 6; /* Voice */
- tspec->ts_info[0] = (tid << 1) |
- (WMM_TSPEC_DIRECTION_BI_DIRECTIONAL << 5) |
- BIT(7);
- tspec->ts_info[1] = up << 3;
- tspec->nominal_msdu_size = host_to_le16(1530);
- tspec->mean_data_rate = host_to_le32(128000); /* bits per second */
- tspec->minimum_phy_rate = host_to_le32(6000000);
- tspec->surplus_bandwidth_allowance = host_to_le16(0x3000); /* 150% */
-}
-
-
-static void ieee80211_tx_addts(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *buf;
- struct ieee80211_mgmt *mgmt;
- size_t alen;
-
- wpa_printf(MSG_DEBUG, "MLME: Send ADDTS Request for Voice TSPEC");
- mgmt = NULL;
- alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt;
-
- buf = wpabuf_alloc(alen + sizeof(struct wmm_tspec_element));
- if (buf == NULL)
- return;
-
- mgmt = wpabuf_put(buf, alen);
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_ACTION);
- mgmt->u.action.category = WLAN_ACTION_WMM;
- mgmt->u.action.u.wmm_action.action_code = WMM_ACTION_CODE_ADDTS_REQ;
- mgmt->u.action.u.wmm_action.dialog_token = 1;
- mgmt->u.action.u.wmm_action.status_code = 0;
-
- ieee80211_build_tspec(buf);
-
- ieee80211_sta_tx(wpa_s, wpabuf_head(buf), wpabuf_len(buf));
- wpabuf_free(buf);
-}
-
-
-static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status,
- int reassoc)
-{
- u8 rates[32];
- size_t rates_len;
- u16 capab_info, status_code, aid;
- struct ieee802_11_elems elems;
- u8 *pos;
-
- /* AssocResp and ReassocResp have identical structure, so process both
- * of them in this function. */
-
- if (wpa_s->mlme.state != IEEE80211_ASSOCIATE) {
- wpa_printf(MSG_DEBUG, "MLME: association frame received from "
- MACSTR ", but not in associate state - ignored",
- MAC2STR(mgmt->sa));
- return;
- }
-
- if (len < 24 + 6) {
- wpa_printf(MSG_DEBUG, "MLME: too short (%lu) association "
- "frame received from " MACSTR " - ignored",
- (unsigned long) len, MAC2STR(mgmt->sa));
- return;
- }
-
- if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: association frame received from "
- "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - "
- "ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
- return;
- }
-
- capab_info = le_to_host16(mgmt->u.assoc_resp.capab_info);
- status_code = le_to_host16(mgmt->u.assoc_resp.status_code);
- aid = le_to_host16(mgmt->u.assoc_resp.aid);
- if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
- wpa_printf(MSG_DEBUG, "MLME: invalid aid value %d; bits 15:14 "
- "not set", aid);
- aid &= ~(BIT(15) | BIT(14));
-
- wpa_printf(MSG_DEBUG, "MLME: RX %sssocResp from " MACSTR
- " (capab=0x%x status=%d aid=%d)",
- reassoc ? "Rea" : "A", MAC2STR(mgmt->sa),
- capab_info, status_code, aid);
-
- pos = mgmt->u.assoc_resp.variable;
- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems, 0)
- == ParseFailed) {
- wpa_printf(MSG_DEBUG, "MLME: failed to parse AssocResp");
- return;
- }
-
- if (status_code != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)",
- status_code);
-#ifdef CONFIG_IEEE80211W
- if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
- elems.timeout_int && elems.timeout_int_len == 5 &&
- elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
- u32 tu, ms;
- tu = WPA_GET_LE32(elems.timeout_int + 1);
- ms = tu * 1024 / 1000;
- wpa_printf(MSG_DEBUG, "MLME: AP rejected association "
- "temporarily; comeback duration %u TU "
- "(%u ms)", tu, ms);
- if (ms > IEEE80211_ASSOC_TIMEOUT) {
- wpa_printf(MSG_DEBUG, "MLME: Update timer "
- "based on comeback duration");
- ieee80211_reschedule_timer(wpa_s, ms);
- }
- }
-#endif /* CONFIG_IEEE80211W */
- return;
- }
-
- if (elems.supp_rates == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: no SuppRates element in "
- "AssocResp");
- return;
- }
-
- if (wpa_s->mlme.auth_alg == WLAN_AUTH_FT) {
- if (!reassoc) {
- wpa_printf(MSG_DEBUG, "MLME: AP tried to use "
- "association, not reassociation, response "
- "with FT");
- return;
- }
- if (wpa_ft_validate_reassoc_resp(
- wpa_s->wpa, pos, len - (pos - (u8 *) mgmt),
- mgmt->sa) < 0) {
- wpa_printf(MSG_DEBUG, "MLME: FT validation of Reassoc"
- "Resp failed");
- return;
- }
- } else if (wpa_sm_set_ft_params(wpa_s->wpa, pos,
- len - (pos - (u8 *) mgmt)) < 0)
- return;
-
- wpa_printf(MSG_DEBUG, "MLME: associated");
- wpa_s->mlme.aid = aid;
- wpa_s->mlme.ap_capab = capab_info;
-
- os_free(wpa_s->mlme.assocresp_ies);
- wpa_s->mlme.assocresp_ies_len = len - (pos - (u8 *) mgmt);
- wpa_s->mlme.assocresp_ies = os_malloc(wpa_s->mlme.assocresp_ies_len);
- if (wpa_s->mlme.assocresp_ies) {
- os_memcpy(wpa_s->mlme.assocresp_ies, pos,
- wpa_s->mlme.assocresp_ies_len);
- }
-
- ieee80211_set_associated(wpa_s, 1);
-
- rates_len = elems.supp_rates_len;
- if (rates_len > sizeof(rates))
- rates_len = sizeof(rates);
- os_memcpy(rates, elems.supp_rates, rates_len);
- if (elems.ext_supp_rates) {
- size_t _len = elems.ext_supp_rates_len;
- if (_len > sizeof(rates) - rates_len)
- _len = sizeof(rates) - rates_len;
- os_memcpy(rates + rates_len, elems.ext_supp_rates, _len);
- rates_len += _len;
- }
-
- if (wpa_drv_set_bssid(wpa_s, wpa_s->bssid) < 0) {
- wpa_printf(MSG_DEBUG, "MLME: failed to set BSSID for the "
- "netstack");
- }
- if (wpa_drv_set_ssid(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) <
- 0) {
- wpa_printf(MSG_DEBUG, "MLME: failed to set SSID for the "
- "netstack");
- }
-
- /* Remove STA entry before adding a new one just in case to avoid
- * problems with existing configuration (e.g., keys). */
- wpa_drv_mlme_remove_sta(wpa_s, wpa_s->bssid);
- if (wpa_drv_mlme_add_sta(wpa_s, wpa_s->bssid, rates, rates_len) < 0) {
- wpa_printf(MSG_DEBUG, "MLME: failed to add STA entry to the "
- "netstack");
- }
-
- if (elems.wmm && wpa_s->mlme.wmm_enabled)
- ieee80211_sta_wmm_params(wpa_s, elems.wmm, elems.wmm_len);
-
- ieee80211_associated(wpa_s);
-
- if (wpa_s->mlme.auth_alg != WLAN_AUTH_FT &&
- os_strcmp(wpa_s->driver->name, "test") == 0 &&
- elems.wmm && wpa_s->mlme.wmm_enabled) {
- /* Test WMM-AC - send ADDTS for WMM TSPEC */
- ieee80211_tx_addts(wpa_s);
- }
-}
-
-
-/* Caller must hold local->sta_bss_lock */
-static void __ieee80211_bss_hash_add(struct wpa_supplicant *wpa_s,
- struct ieee80211_sta_bss *bss)
-{
- bss->hnext = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)];
- wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] = bss;
-}
-
-
-/* Caller must hold local->sta_bss_lock */
-static void __ieee80211_bss_hash_del(struct wpa_supplicant *wpa_s,
- struct ieee80211_sta_bss *bss)
-{
- struct ieee80211_sta_bss *b, *prev = NULL;
- b = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)];
- while (b) {
- if (b == bss) {
- if (prev == NULL) {
- wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]
- = bss->hnext;
- } else {
- prev->hnext = bss->hnext;
- }
- break;
- }
- prev = b;
- b = b->hnext;
- }
-}
-
-
-static struct ieee80211_sta_bss *
-ieee80211_bss_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct ieee80211_sta_bss *bss;
-
- bss = os_zalloc(sizeof(*bss));
- if (bss == NULL)
- return NULL;
- os_memcpy(bss->bssid, bssid, ETH_ALEN);
-
- /* TODO: order by RSSI? */
- bss->next = wpa_s->mlme.sta_bss_list;
- wpa_s->mlme.sta_bss_list = bss;
- __ieee80211_bss_hash_add(wpa_s, bss);
- return bss;
-}
-
-
-static struct ieee80211_sta_bss *
-ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct ieee80211_sta_bss *bss;
-
- bss = wpa_s->mlme.sta_bss_hash[STA_HASH(bssid)];
- while (bss) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
- break;
- bss = bss->hnext;
- }
- return bss;
-}
-
-
-static void ieee80211_bss_free(struct wpa_supplicant *wpa_s,
- struct ieee80211_sta_bss *bss)
-{
- __ieee80211_bss_hash_del(wpa_s, bss);
- os_free(bss->ie);
- os_free(bss->wpa_ie);
- os_free(bss->rsn_ie);
- os_free(bss->wmm_ie);
- os_free(bss->mdie);
- os_free(bss);
-}
-
-
-static void ieee80211_bss_list_deinit(struct wpa_supplicant *wpa_s)
-{
- struct ieee80211_sta_bss *bss, *prev;
-
- bss = wpa_s->mlme.sta_bss_list;
- wpa_s->mlme.sta_bss_list = NULL;
- while (bss) {
- prev = bss;
- bss = bss->next;
- ieee80211_bss_free(wpa_s, prev);
- }
-}
-
-
-static void ieee80211_bss_info(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status,
- int beacon)
-{
- struct ieee802_11_elems elems;
- size_t baselen;
- int channel, invalid = 0, clen;
- struct ieee80211_sta_bss *bss;
- u64 timestamp;
- u8 *pos, *ie_pos;
- size_t ie_len;
-
- if (!beacon && os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN))
- return; /* ignore ProbeResp to foreign address */
-
-#if 0
- wpa_printf(MSG_MSGDUMP, "MLME: RX %s from " MACSTR " to " MACSTR,
- beacon ? "Beacon" : "Probe Response",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
-#endif
-
- baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
- if (baselen > len)
- return;
-
- pos = mgmt->u.beacon.timestamp;
- timestamp = WPA_GET_LE64(pos);
-
-#if 0 /* FIX */
- if (local->conf.mode == IW_MODE_ADHOC && beacon &&
- os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) {
-#ifdef IEEE80211_IBSS_DEBUG
- static unsigned long last_tsf_debug = 0;
- u64 tsf;
- if (local->hw->get_tsf)
- tsf = local->hw->get_tsf(local->mdev);
- else
- tsf = -1LLU;
- if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {
- wpa_printf(MSG_DEBUG, "RX beacon SA=" MACSTR " BSSID="
- MACSTR " TSF=0x%llx BCN=0x%llx diff=%lld "
- "@%ld",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
- tsf, timestamp, tsf - timestamp, jiffies);
- last_tsf_debug = jiffies;
- }
-#endif /* IEEE80211_IBSS_DEBUG */
- }
-#endif
-
- ie_pos = mgmt->u.beacon.variable;
- ie_len = len - baselen;
- if (ieee802_11_parse_elems(ie_pos, ie_len, &elems, 0) == ParseFailed)
- invalid = 1;
-
-#if 0 /* FIX */
- if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates &&
- os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 &&
- (sta = sta_info_get(local, mgmt->sa))) {
- struct ieee80211_rate *rates;
- size_t num_rates;
- u32 supp_rates, prev_rates;
- int i, j, oper_mode;
-
- rates = local->curr_rates;
- num_rates = local->num_curr_rates;
- oper_mode = wpa_s->mlme.sta_scanning ?
- local->scan_oper_phymode : local->conf.phymode;
- for (i = 0; i < local->hw->num_modes; i++) {
- struct ieee80211_hw_modes *mode = &local->hw->modes[i];
- if (oper_mode == mode->mode) {
- rates = mode->rates;
- num_rates = mode->num_rates;
- break;
- }
- }
-
- supp_rates = 0;
- for (i = 0; i < elems.supp_rates_len +
- elems.ext_supp_rates_len; i++) {
- u8 rate = 0;
- int own_rate;
- if (i < elems.supp_rates_len)
- rate = elems.supp_rates[i];
- else if (elems.ext_supp_rates)
- rate = elems.ext_supp_rates
- [i - elems.supp_rates_len];
- own_rate = 5 * (rate & 0x7f);
- if (oper_mode == MODE_ATHEROS_TURBO)
- own_rate *= 2;
- for (j = 0; j < num_rates; j++)
- if (rates[j].rate == own_rate)
- supp_rates |= BIT(j);
- }
-
- prev_rates = sta->supp_rates;
- sta->supp_rates &= supp_rates;
- if (sta->supp_rates == 0) {
- /* No matching rates - this should not really happen.
- * Make sure that at least one rate is marked
- * supported to avoid issues with TX rate ctrl. */
- sta->supp_rates = wpa_s->mlme.supp_rates_bits;
- }
- if (sta->supp_rates != prev_rates) {
- wpa_printf(MSG_DEBUG, "MLME: updated supp_rates set "
- "for " MACSTR " based on beacon info "
- "(0x%x & 0x%x -> 0x%x)",
- MAC2STR(sta->addr), prev_rates,
- supp_rates, sta->supp_rates);
- }
- sta_info_release(local, sta);
- }
-#endif
-
- if (elems.ssid == NULL)
- return;
-
- if (elems.ds_params && elems.ds_params_len == 1)
- channel = elems.ds_params[0];
- else
- channel = rx_status->channel;
-
- bss = ieee80211_bss_get(wpa_s, mgmt->bssid);
- if (bss == NULL) {
- bss = ieee80211_bss_add(wpa_s, mgmt->bssid);
- if (bss == NULL)
- return;
- } else {
-#if 0
- /* TODO: order by RSSI? */
- spin_lock_bh(&local->sta_bss_lock);
- list_move_tail(&bss->list, &local->sta_bss_list);
- spin_unlock_bh(&local->sta_bss_lock);
-#endif
- }
-
- if (bss->probe_resp && beacon) {
- /* Do not allow beacon to override data from Probe Response. */
- return;
- }
-
- bss->beacon_int = le_to_host16(mgmt->u.beacon.beacon_int);
- bss->capability = le_to_host16(mgmt->u.beacon.capab_info);
-
- if (bss->ie == NULL || bss->ie_len < ie_len) {
- os_free(bss->ie);
- bss->ie = os_malloc(ie_len);
- }
- if (bss->ie) {
- os_memcpy(bss->ie, ie_pos, ie_len);
- bss->ie_len = ie_len;
- }
-
- if (elems.ssid && elems.ssid_len <= MAX_SSID_LEN) {
- os_memcpy(bss->ssid, elems.ssid, elems.ssid_len);
- bss->ssid_len = elems.ssid_len;
- }
-
- bss->supp_rates_len = 0;
- if (elems.supp_rates) {
- clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
- if (clen > elems.supp_rates_len)
- clen = elems.supp_rates_len;
- os_memcpy(&bss->supp_rates[bss->supp_rates_len],
- elems.supp_rates, clen);
- bss->supp_rates_len += clen;
- }
- if (elems.ext_supp_rates) {
- clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
- if (clen > elems.ext_supp_rates_len)
- clen = elems.ext_supp_rates_len;
- os_memcpy(&bss->supp_rates[bss->supp_rates_len],
- elems.ext_supp_rates, clen);
- bss->supp_rates_len += clen;
- }
-
- if (elems.wpa_ie &&
- (bss->wpa_ie == NULL || bss->wpa_ie_len != elems.wpa_ie_len ||
- os_memcmp(bss->wpa_ie, elems.wpa_ie, elems.wpa_ie_len))) {
- os_free(bss->wpa_ie);
- bss->wpa_ie = os_malloc(elems.wpa_ie_len + 2);
- if (bss->wpa_ie) {
- os_memcpy(bss->wpa_ie, elems.wpa_ie - 2,
- elems.wpa_ie_len + 2);
- bss->wpa_ie_len = elems.wpa_ie_len + 2;
- } else
- bss->wpa_ie_len = 0;
- } else if (!elems.wpa_ie && bss->wpa_ie) {
- os_free(bss->wpa_ie);
- bss->wpa_ie = NULL;
- bss->wpa_ie_len = 0;
- }
-
- if (elems.rsn_ie &&
- (bss->rsn_ie == NULL || bss->rsn_ie_len != elems.rsn_ie_len ||
- os_memcmp(bss->rsn_ie, elems.rsn_ie, elems.rsn_ie_len))) {
- os_free(bss->rsn_ie);
- bss->rsn_ie = os_malloc(elems.rsn_ie_len + 2);
- if (bss->rsn_ie) {
- os_memcpy(bss->rsn_ie, elems.rsn_ie - 2,
- elems.rsn_ie_len + 2);
- bss->rsn_ie_len = elems.rsn_ie_len + 2;
- } else
- bss->rsn_ie_len = 0;
- } else if (!elems.rsn_ie && bss->rsn_ie) {
- os_free(bss->rsn_ie);
- bss->rsn_ie = NULL;
- bss->rsn_ie_len = 0;
- }
-
- if (elems.wmm &&
- (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_len ||
- os_memcmp(bss->wmm_ie, elems.wmm, elems.wmm_len))) {
- os_free(bss->wmm_ie);
- bss->wmm_ie = os_malloc(elems.wmm_len + 2);
- if (bss->wmm_ie) {
- os_memcpy(bss->wmm_ie, elems.wmm - 2,
- elems.wmm_len + 2);
- bss->wmm_ie_len = elems.wmm_len + 2;
- } else
- bss->wmm_ie_len = 0;
- } else if (!elems.wmm && bss->wmm_ie) {
- os_free(bss->wmm_ie);
- bss->wmm_ie = NULL;
- bss->wmm_ie_len = 0;
- }
-
-#ifdef CONFIG_IEEE80211R
- if (elems.mdie &&
- (bss->mdie == NULL || bss->mdie_len != elems.mdie_len ||
- os_memcmp(bss->mdie, elems.mdie, elems.mdie_len))) {
- os_free(bss->mdie);
- bss->mdie = os_malloc(elems.mdie_len + 2);
- if (bss->mdie) {
- os_memcpy(bss->mdie, elems.mdie - 2,
- elems.mdie_len + 2);
- bss->mdie_len = elems.mdie_len + 2;
- } else
- bss->mdie_len = 0;
- } else if (!elems.mdie && bss->mdie) {
- os_free(bss->mdie);
- bss->mdie = NULL;
- bss->mdie_len = 0;
- }
-#endif /* CONFIG_IEEE80211R */
-
- bss->hw_mode = wpa_s->mlme.phymode;
- bss->channel = channel;
- bss->freq = wpa_s->mlme.freq;
- if (channel != wpa_s->mlme.channel &&
- (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G ||
- wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211B) &&
- channel >= 1 && channel <= 14) {
- static const int freq_list[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484
- };
- /* IEEE 802.11g/b mode can receive packets from neighboring
- * channels, so map the channel into frequency. */
- bss->freq = freq_list[channel - 1];
- }
- bss->timestamp = timestamp;
- os_get_time(&bss->last_update);
- bss->rssi = rx_status->ssi;
- if (!beacon)
- bss->probe_resp++;
-}
-
-
-static void ieee80211_rx_mgmt_probe_resp(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 0);
-}
-
-
-static void ieee80211_rx_mgmt_beacon(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- int use_protection;
- size_t baselen;
- struct ieee802_11_elems elems;
-
- ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 1);
-
- if (!wpa_s->mlme.associated ||
- os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0)
- return;
-
- /* Process beacon from the current BSS */
- baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
- if (baselen > len)
- return;
-
- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
- &elems, 0) == ParseFailed)
- return;
-
- use_protection = 0;
- if (elems.erp_info && elems.erp_info_len >= 1) {
- use_protection =
- (elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0;
- }
-
- if (use_protection != !!wpa_s->mlme.use_protection) {
- wpa_printf(MSG_DEBUG, "MLME: CTS protection %s (BSSID=" MACSTR
- ")",
- use_protection ? "enabled" : "disabled",
- MAC2STR(wpa_s->bssid));
- wpa_s->mlme.use_protection = use_protection ? 1 : 0;
- wpa_s->mlme.cts_protect_erp_frames = use_protection;
- }
-
- if (elems.wmm && wpa_s->mlme.wmm_enabled) {
- ieee80211_sta_wmm_params(wpa_s, elems.wmm,
- elems.wmm_len);
- }
-}
-
-
-static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- int tx_last_beacon, adhoc;
-#if 0 /* FIX */
- struct ieee80211_mgmt *resp;
-#endif
- u8 *pos, *end;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- adhoc = ssid && ssid->mode == WPAS_MODE_IBSS;
-
- if (!adhoc || wpa_s->mlme.state != IEEE80211_IBSS_JOINED ||
- len < 24 + 2 || wpa_s->mlme.probe_resp == NULL)
- return;
-
-#if 0 /* FIX */
- if (local->hw->tx_last_beacon)
- tx_last_beacon = local->hw->tx_last_beacon(local->mdev);
- else
-#endif
- tx_last_beacon = 1;
-
-#ifdef IEEE80211_IBSS_DEBUG
- wpa_printf(MSG_DEBUG, "MLME: RX ProbeReq SA=" MACSTR " DA=" MACSTR
- " BSSID=" MACSTR " (tx_last_beacon=%d)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- MAC2STR(mgmt->bssid), tx_last_beacon);
-#endif /* IEEE80211_IBSS_DEBUG */
-
- if (!tx_last_beacon)
- return;
-
- if (os_memcmp(mgmt->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
- os_memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
- return;
-
- end = ((u8 *) mgmt) + len;
- pos = mgmt->u.probe_req.variable;
- if (pos[0] != WLAN_EID_SSID ||
- pos + 2 + pos[1] > end) {
- wpa_printf(MSG_DEBUG, "MLME: Invalid SSID IE in ProbeReq from "
- MACSTR, MAC2STR(mgmt->sa));
- return;
- }
- if (pos[1] != 0 &&
- (pos[1] != wpa_s->mlme.ssid_len ||
- os_memcmp(pos + 2, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) != 0))
- {
- /* Ignore ProbeReq for foreign SSID */
- return;
- }
-
-#if 0 /* FIX */
- /* Reply with ProbeResp */
- skb = skb_copy(wpa_s->mlme.probe_resp, GFP_ATOMIC);
- if (skb == NULL)
- return;
-
- resp = (struct ieee80211_mgmt *) skb->data;
- os_memcpy(resp->da, mgmt->sa, ETH_ALEN);
-#ifdef IEEE80211_IBSS_DEBUG
- wpa_printf(MSG_DEBUG, "MLME: Sending ProbeResp to " MACSTR,
- MAC2STR(resp->da));
-#endif /* IEEE80211_IBSS_DEBUG */
- ieee80211_sta_tx(wpa_s, skb, 0, 1);
-#endif
-}
-
-
-#ifdef CONFIG_IEEE80211R
-static void ieee80211_rx_mgmt_ft_action(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- union wpa_event_data data;
- u16 status;
- u8 *sta_addr, *target_ap_addr;
-
- if (len < 24 + 1 + sizeof(mgmt->u.action.u.ft_action_resp)) {
- wpa_printf(MSG_DEBUG, "MLME: Too short FT Action frame");
- return;
- }
-
- /*
- * Only FT Action Response is needed for now since reservation
- * protocol is not supported.
- */
- if (mgmt->u.action.u.ft_action_resp.action != 2) {
- wpa_printf(MSG_DEBUG, "MLME: Unexpected FT Action %d",
- mgmt->u.action.u.ft_action_resp.action);
- return;
- }
-
- status = le_to_host16(mgmt->u.action.u.ft_action_resp.status_code);
- sta_addr = mgmt->u.action.u.ft_action_resp.sta_addr;
- target_ap_addr = mgmt->u.action.u.ft_action_resp.target_ap_addr;
- wpa_printf(MSG_DEBUG, "MLME: Received FT Action Response: STA " MACSTR
- " TargetAP " MACSTR " Status Code %d",
- MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
- if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: Foreign STA Address " MACSTR
- " in FT Action Response", MAC2STR(sta_addr));
- return;
- }
-
- if (status) {
- wpa_printf(MSG_DEBUG, "MLME: FT Action Response indicates "
- "failure (status code %d)", status);
- /* TODO: report error to FT code(?) */
- return;
- }
-
- os_memset(&data, 0, sizeof(data));
- data.ft_ies.ies = mgmt->u.action.u.ft_action_resp.variable;
- data.ft_ies.ies_len = len - (mgmt->u.action.u.ft_action_resp.variable -
- (u8 *) mgmt);
- data.ft_ies.ft_action = 1;
- os_memcpy(data.ft_ies.target_ap, target_ap_addr, ETH_ALEN);
- wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data);
- /* TODO: should only re-associate, if EVENT_FT_RESPONSE was processed
- * successfully */
- wpa_s->mlme.prev_bssid_set = 1;
- wpa_s->mlme.auth_alg = WLAN_AUTH_FT;
- os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN);
- os_memcpy(wpa_s->bssid, target_ap_addr, ETH_ALEN);
- ieee80211_associate(wpa_s);
-}
-#endif /* CONFIG_IEEE80211R */
-
-
-#ifdef CONFIG_IEEE80211W
-
-/* MLME-SAQuery.response */
-static int ieee80211_sta_send_sa_query_resp(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *trans_id)
-{
- struct ieee80211_mgmt *mgmt;
- int res;
- size_t len;
-
- mgmt = os_zalloc(sizeof(*mgmt));
- if (mgmt == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
- "SA Query action frame");
- return -1;
- }
-
- len = 24;
- os_memcpy(mgmt->da, addr, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_ACTION);
- mgmt->u.action.category = WLAN_ACTION_SA_QUERY;
- mgmt->u.action.u.sa_query_resp.action = WLAN_SA_QUERY_RESPONSE;
- os_memcpy(mgmt->u.action.u.sa_query_resp.trans_id, trans_id,
- WLAN_SA_QUERY_TR_ID_LEN);
- len += 1 + sizeof(mgmt->u.action.u.sa_query_resp);
-
- res = ieee80211_sta_tx(wpa_s, (u8 *) mgmt, len);
- os_free(mgmt);
-
- return res;
-}
-
-
-static void ieee80211_rx_mgmt_sa_query_action(
- struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- if (len < 24 + 1 + sizeof(mgmt->u.action.u.sa_query_req)) {
- wpa_printf(MSG_DEBUG, "MLME: Too short SA Query Action frame");
- return;
- }
-
- if (mgmt->u.action.u.sa_query_req.action != WLAN_SA_QUERY_REQUEST) {
- wpa_printf(MSG_DEBUG, "MLME: Unexpected SA Query Action %d",
- mgmt->u.action.u.sa_query_req.action);
- return;
- }
-
- if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "MLME: Ignore SA Query from unknown "
- "source " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- if (wpa_s->mlme.state == IEEE80211_ASSOCIATE) {
- wpa_printf(MSG_DEBUG, "MLME: Ignore SA query request during "
- "association process");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "MLME: Replying to SA Query request");
- ieee80211_sta_send_sa_query_resp(wpa_s, mgmt->sa, mgmt->u.action.u.
- sa_query_req.trans_id);
-}
-
-#endif /* CONFIG_IEEE80211W */
-
-
-static void dump_tspec(struct wmm_tspec_element *tspec)
-{
- int up, psb, dir, tid;
- u16 val;
-
- up = (tspec->ts_info[1] >> 3) & 0x07;
- psb = (tspec->ts_info[1] >> 2) & 0x01;
- dir = (tspec->ts_info[0] >> 5) & 0x03;
- tid = (tspec->ts_info[0] >> 1) & 0x0f;
- wpa_printf(MSG_DEBUG, "WMM: TS Info: UP=%d PSB=%d Direction=%d TID=%d",
- up, psb, dir, tid);
- val = le_to_host16(tspec->nominal_msdu_size);
- wpa_printf(MSG_DEBUG, "WMM: Nominal MSDU Size: %d%s",
- val & 0x7fff, val & 0x8000 ? " (fixed)" : "");
- wpa_printf(MSG_DEBUG, "WMM: Mean Data Rate: %u bps",
- le_to_host32(tspec->mean_data_rate));
- wpa_printf(MSG_DEBUG, "WMM: Minimum PHY Rate: %u bps",
- le_to_host32(tspec->minimum_phy_rate));
- val = le_to_host16(tspec->surplus_bandwidth_allowance);
- wpa_printf(MSG_DEBUG, "WMM: Surplus Bandwidth Allowance: %u.%04u",
- val >> 13, 10000 * (val & 0x1fff) / 0x2000);
- val = le_to_host16(tspec->medium_time);
- wpa_printf(MSG_DEBUG, "WMM: Medium Time: %u (= %u usec/sec)",
- val, 32 * val);
-}
-
-
-static int is_wmm_tspec(const u8 *ie, size_t len)
-{
- const struct wmm_tspec_element *tspec;
-
- if (len < sizeof(*tspec))
- return 0;
-
- tspec = (const struct wmm_tspec_element *) ie;
- if (tspec->eid != WLAN_EID_VENDOR_SPECIFIC ||
- tspec->length < sizeof(*tspec) - 2 ||
- tspec->oui[0] != 0x00 || tspec->oui[1] != 0x50 ||
- tspec->oui[2] != 0xf2 || tspec->oui_type != 2 ||
- tspec->oui_subtype != 2 || tspec->version != 1)
- return 0;
-
- return 1;
-}
-
-
-static void ieee80211_rx_addts_resp(
- struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
- size_t var_len)
-{
- struct wmm_tspec_element *tspec;
-
- wpa_printf(MSG_DEBUG, "WMM: Received ADDTS Response");
- wpa_hexdump(MSG_MSGDUMP, "WMM: ADDTS Response IE(s)",
- mgmt->u.action.u.wmm_action.variable, var_len);
- if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len))
- return;
- tspec = (struct wmm_tspec_element *)
- mgmt->u.action.u.wmm_action.variable;
- dump_tspec(tspec);
-}
-
-
-static void ieee80211_rx_delts(
- struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
- size_t var_len)
-{
- struct wmm_tspec_element *tspec;
-
- wpa_printf(MSG_DEBUG, "WMM: Received DELTS");
- wpa_hexdump(MSG_MSGDUMP, "WMM: DELTS IE(s)",
- mgmt->u.action.u.wmm_action.variable, var_len);
- if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len))
- return;
- tspec = (struct wmm_tspec_element *)
- mgmt->u.action.u.wmm_action.variable;
- dump_tspec(tspec);
-}
-
-
-static void ieee80211_rx_mgmt_wmm_action(
- struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- size_t alen;
-
- alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt;
- if (len < alen) {
- wpa_printf(MSG_DEBUG, "WMM: Received Action frame too short");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "WMM: Received Action frame: Action Code %d, "
- "Dialog Token %d, Status Code %d",
- mgmt->u.action.u.wmm_action.action_code,
- mgmt->u.action.u.wmm_action.dialog_token,
- mgmt->u.action.u.wmm_action.status_code);
-
- switch (mgmt->u.action.u.wmm_action.action_code) {
- case WMM_ACTION_CODE_ADDTS_RESP:
- ieee80211_rx_addts_resp(wpa_s, mgmt, len, len - alen);
- break;
- case WMM_ACTION_CODE_DELTS:
- ieee80211_rx_delts(wpa_s, mgmt, len, len - alen);
- break;
- default:
- wpa_printf(MSG_DEBUG, "WMM: Unsupported Action Code %d",
- mgmt->u.action.u.wmm_action.action_code);
- break;
- }
-}
-
-
-static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s,
- struct ieee80211_mgmt *mgmt,
- size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- wpa_printf(MSG_DEBUG, "MLME: received Action frame");
-
- if (len < 25)
- return;
-
- switch (mgmt->u.action.category) {
-#ifdef CONFIG_IEEE80211R
- case WLAN_ACTION_FT:
- ieee80211_rx_mgmt_ft_action(wpa_s, mgmt, len, rx_status);
- break;
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
- case WLAN_ACTION_SA_QUERY:
- ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status);
- break;
-#endif /* CONFIG_IEEE80211W */
- case WLAN_ACTION_WMM:
- ieee80211_rx_mgmt_wmm_action(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_ACTION_PUBLIC:
- if (wpa_s->mlme.public_action_cb) {
- wpa_s->mlme.public_action_cb(
- wpa_s->mlme.public_action_cb_ctx,
- (u8 *) mgmt, len, rx_status->freq);
- return;
- }
- break;
- default:
- wpa_printf(MSG_DEBUG, "MLME: unknown Action Category %d",
- mgmt->u.action.category);
- break;
- }
-}
-
-
-static void ieee80211_sta_rx_mgmt(struct wpa_supplicant *wpa_s,
- const u8 *buf, size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_mgmt *mgmt;
- u16 fc;
-
- if (len < 24)
- return;
-
- mgmt = (struct ieee80211_mgmt *) buf;
- fc = le_to_host16(mgmt->frame_control);
-
- switch (WLAN_FC_GET_STYPE(fc)) {
- case WLAN_FC_STYPE_PROBE_REQ:
- ieee80211_rx_mgmt_probe_req(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_FC_STYPE_PROBE_RESP:
- ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_FC_STYPE_BEACON:
- ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_FC_STYPE_AUTH:
- ieee80211_rx_mgmt_auth(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_FC_STYPE_ASSOC_RESP:
- ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 0);
- break;
- case WLAN_FC_STYPE_REASSOC_RESP:
- ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 1);
- break;
- case WLAN_FC_STYPE_DEAUTH:
- ieee80211_rx_mgmt_deauth(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_FC_STYPE_DISASSOC:
- ieee80211_rx_mgmt_disassoc(wpa_s, mgmt, len, rx_status);
- break;
- case WLAN_FC_STYPE_ACTION:
- ieee80211_rx_mgmt_action(wpa_s, mgmt, len, rx_status);
- break;
- default:
- wpa_printf(MSG_DEBUG, "MLME: received unknown management "
- "frame - stype=%d", WLAN_FC_GET_STYPE(fc));
- break;
- }
-}
-
-
-static void ieee80211_sta_rx_scan(struct wpa_supplicant *wpa_s,
- const u8 *buf, size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_mgmt *mgmt;
- u16 fc;
-
- if (len < 24)
- return;
-
- mgmt = (struct ieee80211_mgmt *) buf;
- fc = le_to_host16(mgmt->frame_control);
-
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) {
- if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
- ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt,
- len, rx_status);
- } else if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) {
- ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status);
- }
- }
-}
-
-
-static int ieee80211_sta_active_ibss(struct wpa_supplicant *wpa_s)
-{
- int active = 0;
-
-#if 0 /* FIX */
- list_for_each(ptr, &local->sta_list) {
- sta = list_entry(ptr, struct sta_info, list);
- if (sta->dev == dev &&
- time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
- jiffies)) {
- active++;
- break;
- }
- }
-#endif
-
- return active;
-}
-
-
-static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s)
-{
-#if 0 /* FIX */
- list_for_each_safe(ptr, n, &local->sta_list) {
- sta = list_entry(ptr, struct sta_info, list);
- if (time_after(jiffies, sta->last_rx +
- IEEE80211_IBSS_INACTIVITY_LIMIT)) {
- wpa_printf(MSG_DEBUG, "MLME: expiring inactive STA "
- MACSTR, MAC2STR(sta->addr));
- sta_info_free(local, sta, 1);
- }
- }
-#endif
-}
-
-
-static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s)
-{
- struct wpa_driver_scan_params params;
-
- ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL);
-
- ieee80211_sta_expire(wpa_s);
- if (ieee80211_sta_active_ibss(wpa_s))
- return;
-
- wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for "
- "other IBSS networks with same SSID (merge)");
- os_memset(&params, 0, sizeof(params));
- params.ssids[0].ssid = wpa_s->mlme.ssid;
- params.ssids[0].ssid_len = wpa_s->mlme.ssid_len;
- params.num_ssids = wpa_s->mlme.ssid_len ? 1 : 0;
- ieee80211_sta_req_scan(wpa_s, &params);
-}
-
-
-static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- switch (wpa_s->mlme.state) {
- case IEEE80211_DISABLED:
- break;
- case IEEE80211_AUTHENTICATE:
- ieee80211_authenticate(wpa_s);
- break;
- case IEEE80211_ASSOCIATE:
- ieee80211_associate(wpa_s);
- break;
- case IEEE80211_ASSOCIATED:
- ieee80211_associated(wpa_s);
- break;
- case IEEE80211_IBSS_SEARCH:
- ieee80211_sta_find_ibss(wpa_s);
- break;
- case IEEE80211_IBSS_JOINED:
- ieee80211_sta_merge_ibss(wpa_s);
- break;
- default:
- wpa_printf(MSG_DEBUG, "ieee80211_sta_timer: Unknown state %d",
- wpa_s->mlme.state);
- break;
- }
-
- if (ieee80211_privacy_mismatch(wpa_s)) {
- wpa_printf(MSG_DEBUG, "MLME: privacy configuration mismatch "
- "and mixed-cell disabled - disassociate");
-
- ieee80211_send_disassoc(wpa_s, WLAN_REASON_UNSPECIFIED);
- ieee80211_set_associated(wpa_s, 0);
- }
-}
-
-
-static void ieee80211_sta_new_auth(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- if (ssid && ssid->mode != WPAS_MODE_INFRA)
- return;
-
-#if 0 /* FIX */
- if (local->hw->reset_tsf) {
- /* Reset own TSF to allow time synchronization work. */
- local->hw->reset_tsf(local->mdev);
- }
-#endif
-
- wpa_s->mlme.wmm_last_param_set = -1; /* allow any WMM update */
-
-
- if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_OPEN)
- wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN;
- else if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_SHARED)
- wpa_s->mlme.auth_alg = WLAN_AUTH_SHARED_KEY;
- else if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_LEAP)
- wpa_s->mlme.auth_alg = WLAN_AUTH_LEAP;
- else
- wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN;
- wpa_printf(MSG_DEBUG, "MLME: Initial auth_alg=%d",
- wpa_s->mlme.auth_alg);
- wpa_s->mlme.auth_transaction = -1;
- wpa_s->mlme.auth_tries = wpa_s->mlme.assoc_tries = 0;
- ieee80211_authenticate(wpa_s);
-}
-
-
-static int ieee80211_ibss_allowed(struct wpa_supplicant *wpa_s)
-{
-#if 0 /* FIX */
- int m, c;
-
- for (m = 0; m < local->hw->num_modes; m++) {
- struct ieee80211_hw_modes *mode = &local->hw->modes[m];
- if (mode->mode != local->conf.phymode)
- continue;
- for (c = 0; c < mode->num_channels; c++) {
- struct ieee80211_channel *chan = &mode->channels[c];
- if (chan->flag & IEEE80211_CHAN_W_SCAN &&
- chan->chan == local->conf.channel) {
- if (chan->flag & IEEE80211_CHAN_W_IBSS)
- return 1;
- break;
- }
- }
- }
-#endif
-
- return 0;
-}
-
-
-static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s,
- struct ieee80211_sta_bss *bss)
-{
- int res = 0, rates, done = 0, bssid_changed;
- struct ieee80211_mgmt *mgmt;
-#if 0 /* FIX */
- struct ieee80211_tx_control control;
- struct ieee80211_rate *rate;
- struct rate_control_extra extra;
-#endif
- u8 *pos, *buf;
- size_t len;
-
- /* Remove possible STA entries from other IBSS networks. */
-#if 0 /* FIX */
- sta_info_flush(local, NULL);
-
- if (local->hw->reset_tsf) {
- /* Reset own TSF to allow time synchronization work. */
- local->hw->reset_tsf(local->mdev);
- }
-#endif
- bssid_changed = os_memcmp(wpa_s->bssid, bss->bssid, ETH_ALEN);
- os_memcpy(wpa_s->bssid, bss->bssid, ETH_ALEN);
- if (bssid_changed)
- wpas_notify_bssid_changed(wpa_s);
-
-#if 0 /* FIX */
- local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
-
- sdata->drop_unencrypted = bss->capability &
- host_to_le16(WLAN_CAPABILITY_PRIVACY) ? 1 : 0;
-#endif
-
-#if 0 /* FIX */
- os_memset(&rq, 0, sizeof(rq));
- rq.m = bss->freq * 100000;
- rq.e = 1;
- res = ieee80211_ioctl_siwfreq(wpa_s, NULL, &rq, NULL);
-#endif
-
- if (!ieee80211_ibss_allowed(wpa_s)) {
-#if 0 /* FIX */
- wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed on channel %d "
- "(%d MHz)", local->conf.channel,
- local->conf.freq);
-#endif
- return -1;
- }
-
- /* Set beacon template based on scan results */
- buf = os_malloc(400);
- len = 0;
- do {
- if (buf == NULL)
- break;
-
- mgmt = (struct ieee80211_mgmt *) buf;
- len += 24 + sizeof(mgmt->u.beacon);
- os_memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_BEACON);
- os_memset(mgmt->da, 0xff, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
-#if 0 /* FIX */
- mgmt->u.beacon.beacon_int =
- host_to_le16(local->conf.beacon_int);
-#endif
- mgmt->u.beacon.capab_info = host_to_le16(bss->capability);
-
- pos = buf + len;
- len += 2 + wpa_s->mlme.ssid_len;
- *pos++ = WLAN_EID_SSID;
- *pos++ = wpa_s->mlme.ssid_len;
- os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
-
- rates = bss->supp_rates_len;
- if (rates > 8)
- rates = 8;
- pos = buf + len;
- len += 2 + rates;
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos++ = rates;
- os_memcpy(pos, bss->supp_rates, rates);
-
- pos = buf + len;
- len += 2 + 1;
- *pos++ = WLAN_EID_DS_PARAMS;
- *pos++ = 1;
- *pos++ = bss->channel;
-
- pos = buf + len;
- len += 2 + 2;
- *pos++ = WLAN_EID_IBSS_PARAMS;
- *pos++ = 2;
- /* FIX: set ATIM window based on scan results */
- *pos++ = 0;
- *pos++ = 0;
-
- if (bss->supp_rates_len > 8) {
- rates = bss->supp_rates_len - 8;
- pos = buf + len;
- len += 2 + rates;
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos++ = rates;
- os_memcpy(pos, &bss->supp_rates[8], rates);
- }
-
-#if 0 /* FIX */
- os_memset(&control, 0, sizeof(control));
- control.pkt_type = PKT_PROBE_RESP;
- os_memset(&extra, 0, sizeof(extra));
- extra.endidx = local->num_curr_rates;
- rate = rate_control_get_rate(wpa_s, skb, &extra);
- if (rate == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: Failed to determine TX "
- "rate for IBSS beacon");
- break;
- }
- control.tx_rate = (wpa_s->mlme.short_preamble &&
- (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
- rate->val2 : rate->val;
- control.antenna_sel = local->conf.antenna_sel;
- control.power_level = local->conf.power_level;
- control.no_ack = 1;
- control.retry_limit = 1;
- control.rts_cts_duration = 0;
-#endif
-
-#if 0 /* FIX */
- wpa_s->mlme.probe_resp = skb_copy(skb, GFP_ATOMIC);
- if (wpa_s->mlme.probe_resp) {
- mgmt = (struct ieee80211_mgmt *)
- wpa_s->mlme.probe_resp->data;
- mgmt->frame_control =
- IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_PROBE_RESP);
- } else {
- wpa_printf(MSG_DEBUG, "MLME: Could not allocate "
- "ProbeResp template for IBSS");
- }
-
- if (local->hw->beacon_update &&
- local->hw->beacon_update(wpa_s, skb, &control) == 0) {
- wpa_printf(MSG_DEBUG, "MLME: Configured IBSS beacon "
- "template based on scan results");
- skb = NULL;
- }
-
- rates = 0;
- for (i = 0; i < bss->supp_rates_len; i++) {
- int rate = (bss->supp_rates[i] & 0x7f) * 5;
- if (local->conf.phymode == MODE_ATHEROS_TURBO)
- rate *= 2;
- for (j = 0; j < local->num_curr_rates; j++)
- if (local->curr_rates[j] == rate)
- rates |= BIT(j);
- }
- wpa_s->mlme.supp_rates_bits = rates;
-#endif
- done = 1;
- } while (0);
-
- os_free(buf);
- if (!done) {
- wpa_printf(MSG_DEBUG, "MLME: Failed to configure IBSS beacon "
- "template");
- }
-
- wpa_s->mlme.state = IEEE80211_IBSS_JOINED;
- ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL);
-
- return res;
-}
-
-
-#if 0 /* FIX */
-static int ieee80211_sta_create_ibss(struct wpa_supplicant *wpa_s)
-{
- struct ieee80211_sta_bss *bss;
- u8 bssid[ETH_ALEN], *pos;
- int i;
-
-#if 0
- /* Easier testing, use fixed BSSID. */
- os_memset(bssid, 0xfe, ETH_ALEN);
-#else
- /* Generate random, not broadcast, locally administered BSSID. Mix in
- * own MAC address to make sure that devices that do not have proper
- * random number generator get different BSSID. */
- os_get_random(bssid, ETH_ALEN);
- for (i = 0; i < ETH_ALEN; i++)
- bssid[i] ^= wpa_s->own_addr[i];
- bssid[0] &= ~0x01;
- bssid[0] |= 0x02;
-#endif
-
- wpa_printf(MSG_DEBUG, "MLME: Creating new IBSS network, BSSID "
- MACSTR "", MAC2STR(bssid));
-
- bss = ieee80211_bss_add(wpa_s, bssid);
- if (bss == NULL)
- return -ENOMEM;
-
-#if 0 /* FIX */
- if (local->conf.beacon_int == 0)
- local->conf.beacon_int = 100;
- bss->beacon_int = local->conf.beacon_int;
- bss->hw_mode = local->conf.phymode;
- bss->channel = local->conf.channel;
- bss->freq = local->conf.freq;
-#endif
- os_get_time(&bss->last_update);
- bss->capability = host_to_le16(WLAN_CAPABILITY_IBSS);
-#if 0 /* FIX */
- if (sdata->default_key) {
- bss->capability |= host_to_le16(WLAN_CAPABILITY_PRIVACY);
- } else
- sdata->drop_unencrypted = 0;
- bss->supp_rates_len = local->num_curr_rates;
-#endif
- pos = bss->supp_rates;
-#if 0 /* FIX */
- for (i = 0; i < local->num_curr_rates; i++) {
- int rate = local->curr_rates[i];
- if (local->conf.phymode == MODE_ATHEROS_TURBO)
- rate /= 2;
- *pos++ = (u8) (rate / 5);
- }
-#endif
-
- return ieee80211_sta_join_ibss(wpa_s, bss);
-}
-#endif
-
-
-static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s)
-{
- struct ieee80211_sta_bss *bss;
- int found = 0;
- u8 bssid[ETH_ALEN];
- int active_ibss;
- struct os_time now;
-
- if (wpa_s->mlme.ssid_len == 0)
- return -EINVAL;
-
- active_ibss = ieee80211_sta_active_ibss(wpa_s);
-#ifdef IEEE80211_IBSS_DEBUG
- wpa_printf(MSG_DEBUG, "MLME: sta_find_ibss (active_ibss=%d)",
- active_ibss);
-#endif /* IEEE80211_IBSS_DEBUG */
- for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) {
- if (wpa_s->mlme.ssid_len != bss->ssid_len ||
- os_memcmp(wpa_s->mlme.ssid, bss->ssid, bss->ssid_len) != 0
- || !(bss->capability & WLAN_CAPABILITY_IBSS))
- continue;
-#ifdef IEEE80211_IBSS_DEBUG
- wpa_printf(MSG_DEBUG, " bssid=" MACSTR " found",
- MAC2STR(bss->bssid));
-#endif /* IEEE80211_IBSS_DEBUG */
- os_memcpy(bssid, bss->bssid, ETH_ALEN);
- found = 1;
- if (active_ibss ||
- os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)
- break;
- }
-
-#ifdef IEEE80211_IBSS_DEBUG
- wpa_printf(MSG_DEBUG, " sta_find_ibss: selected " MACSTR " current "
- MACSTR, MAC2STR(bssid), MAC2STR(wpa_s->bssid));
-#endif /* IEEE80211_IBSS_DEBUG */
- if (found && os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) != 0 &&
- (bss = ieee80211_bss_get(wpa_s, bssid))) {
- wpa_printf(MSG_DEBUG, "MLME: Selected IBSS BSSID " MACSTR
- " based on configured SSID",
- MAC2STR(bssid));
- return ieee80211_sta_join_ibss(wpa_s, bss);
- }
-#ifdef IEEE80211_IBSS_DEBUG
- wpa_printf(MSG_DEBUG, " did not try to join ibss");
-#endif /* IEEE80211_IBSS_DEBUG */
-
- /* Selected IBSS not found in current scan results - try to scan */
- os_get_time(&now);
-#if 0 /* FIX */
- if (wpa_s->mlme.state == IEEE80211_IBSS_JOINED &&
- !ieee80211_sta_active_ibss(wpa_s)) {
- ieee80211_reschedule_timer(wpa_s,
- IEEE80211_IBSS_MERGE_INTERVAL);
- } else if (time_after(jiffies, wpa_s->mlme.last_scan_completed +
- IEEE80211_SCAN_INTERVAL)) {
- wpa_printf(MSG_DEBUG, "MLME: Trigger new scan to find an IBSS "
- "to join");
- return ieee80211_sta_req_scan(wpa_s->mlme.ssid,
- wpa_s->mlme.ssid_len);
- } else if (wpa_s->mlme.state != IEEE80211_IBSS_JOINED) {
- int interval = IEEE80211_SCAN_INTERVAL;
-
- if (time_after(jiffies, wpa_s->mlme.ibss_join_req +
- IEEE80211_IBSS_JOIN_TIMEOUT)) {
- if (wpa_s->mlme.create_ibss &&
- ieee80211_ibss_allowed(wpa_s))
- return ieee80211_sta_create_ibss(wpa_s);
- if (wpa_s->mlme.create_ibss) {
- wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed "
- "on the configured channel %d "
- "(%d MHz)",
- local->conf.channel,
- local->conf.freq);
- }
-
- /* No IBSS found - decrease scan interval and continue
- * scanning. */
- interval = IEEE80211_SCAN_INTERVAL_SLOW;
- }
-
- wpa_s->mlme.state = IEEE80211_IBSS_SEARCH;
- ieee80211_reschedule_timer(wpa_s, interval);
- return 0;
- }
-#endif
-
- return 0;
-}
-
-
-int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid,
- size_t *len)
-{
- os_memcpy(ssid, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
- *len = wpa_s->mlme.ssid_len;
- return 0;
-}
-
-
-int ieee80211_sta_associate(struct wpa_supplicant *wpa_s,
- struct wpa_driver_associate_params *params)
-{
- struct ieee80211_sta_bss *bss;
- int bssid_changed;
-
- wpa_s->mlme.bssid_set = 0;
- wpa_s->mlme.freq = params->freq;
- if (params->bssid) {
- bssid_changed = os_memcmp(wpa_s->bssid, params->bssid,
- ETH_ALEN);
- os_memcpy(wpa_s->bssid, params->bssid, ETH_ALEN);
- if (bssid_changed)
- wpas_notify_bssid_changed(wpa_s);
-
- if (!is_zero_ether_addr(params->bssid))
- wpa_s->mlme.bssid_set = 1;
- bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
- if (bss) {
- wpa_s->mlme.phymode = bss->hw_mode;
- wpa_s->mlme.channel = bss->channel;
- wpa_s->mlme.freq = bss->freq;
- }
- }
-
-#if 0 /* FIX */
- /* TODO: This should always be done for IBSS, even if IEEE80211_QOS is
- * not defined. */
- if (local->hw->conf_tx) {
- struct ieee80211_tx_queue_params qparam;
- int i;
-
- os_memset(&qparam, 0, sizeof(qparam));
- /* TODO: are these ok defaults for all hw_modes? */
- qparam.aifs = 2;
- qparam.cw_min =
- local->conf.phymode == MODE_IEEE80211B ? 31 : 15;
- qparam.cw_max = 1023;
- qparam.burst_time = 0;
- for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++)
- {
- local->hw->conf_tx(wpa_s, i + IEEE80211_TX_QUEUE_DATA0,
- &qparam);
- }
- /* IBSS uses different parameters for Beacon sending */
- qparam.cw_min++;
- qparam.cw_min *= 2;
- qparam.cw_min--;
- local->hw->conf_tx(wpa_s, IEEE80211_TX_QUEUE_BEACON, &qparam);
- }
-#endif
-
- if (wpa_s->mlme.ssid_len != params->ssid_len ||
- os_memcmp(wpa_s->mlme.ssid, params->ssid, params->ssid_len) != 0)
- wpa_s->mlme.prev_bssid_set = 0;
- os_memcpy(wpa_s->mlme.ssid, params->ssid, params->ssid_len);
- os_memset(wpa_s->mlme.ssid + params->ssid_len, 0,
- MAX_SSID_LEN - params->ssid_len);
- wpa_s->mlme.ssid_len = params->ssid_len;
- wpa_s->mlme.ssid_set = 1;
-
- os_free(wpa_s->mlme.extra_ie);
- if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
- wpa_s->mlme.extra_ie = NULL;
- wpa_s->mlme.extra_ie_len = 0;
- } else {
- wpa_s->mlme.extra_ie = os_malloc(params->wpa_ie_len);
- if (wpa_s->mlme.extra_ie == NULL) {
- wpa_s->mlme.extra_ie_len = 0;
- return -1;
- }
- os_memcpy(wpa_s->mlme.extra_ie, params->wpa_ie,
- params->wpa_ie_len);
- wpa_s->mlme.extra_ie_len = params->wpa_ie_len;
- }
-
- wpa_s->mlme.key_mgmt = params->key_mgmt_suite;
-
- ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode,
- wpa_s->mlme.channel, wpa_s->mlme.freq);
-
- if (params->mode == WPAS_MODE_IBSS && !wpa_s->mlme.bssid_set) {
- os_get_time(&wpa_s->mlme.ibss_join_req);
- wpa_s->mlme.state = IEEE80211_IBSS_SEARCH;
- return ieee80211_sta_find_ibss(wpa_s);
- }
-
- if (wpa_s->mlme.bssid_set)
- ieee80211_sta_new_auth(wpa_s);
-
- return 0;
-}
-
-
-static void ieee80211_sta_save_oper_chan(struct wpa_supplicant *wpa_s)
-{
- wpa_s->mlme.scan_oper_channel = wpa_s->mlme.channel;
- wpa_s->mlme.scan_oper_freq = wpa_s->mlme.freq;
- wpa_s->mlme.scan_oper_phymode = wpa_s->mlme.phymode;
-}
-
-
-static int ieee80211_sta_restore_oper_chan(struct wpa_supplicant *wpa_s)
-{
- wpa_s->mlme.channel = wpa_s->mlme.scan_oper_channel;
- wpa_s->mlme.freq = wpa_s->mlme.scan_oper_freq;
- wpa_s->mlme.phymode = wpa_s->mlme.scan_oper_phymode;
- if (wpa_s->mlme.freq == 0)
- return 0;
- return ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode,
- wpa_s->mlme.channel,
- wpa_s->mlme.freq);
-}
-
-
-static int ieee80211_active_scan(struct wpa_supplicant *wpa_s)
-{
- size_t m;
- int c;
-
- for (m = 0; m < wpa_s->mlme.num_modes; m++) {
- struct hostapd_hw_modes *mode = &wpa_s->mlme.modes[m];
- if ((int) mode->mode != (int) wpa_s->mlme.phymode)
- continue;
- for (c = 0; c < mode->num_channels; c++) {
- struct hostapd_channel_data *chan = &mode->channels[c];
- if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
- chan->chan == wpa_s->mlme.channel) {
- if (!(chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN))
- return 1;
- break;
- }
- }
- }
-
- return 0;
-}
-
-
-static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct hostapd_hw_modes *mode;
- struct hostapd_channel_data *chan;
- int skip = 0;
- int timeout = 0;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int adhoc;
-
- if (!wpa_s->mlme.sta_scanning || wpa_s->mlme.modes == NULL)
- return;
-
- adhoc = ssid && ssid->mode == 1;
-
- switch (wpa_s->mlme.scan_state) {
- case SCAN_SET_CHANNEL:
- mode = &wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx];
- if (wpa_s->mlme.scan_hw_mode_idx >=
- (int) wpa_s->mlme.num_modes ||
- (wpa_s->mlme.scan_hw_mode_idx + 1 ==
- (int) wpa_s->mlme.num_modes
- && wpa_s->mlme.scan_channel_idx >= mode->num_channels)) {
- if (ieee80211_sta_restore_oper_chan(wpa_s)) {
- wpa_printf(MSG_DEBUG, "MLME: failed to "
- "restore operational channel after "
- "scan");
- }
- wpa_printf(MSG_DEBUG, "MLME: scan completed");
- wpa_s->mlme.sta_scanning = 0;
- os_get_time(&wpa_s->mlme.last_scan_completed);
- wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL);
- if (adhoc) {
- if (!wpa_s->mlme.bssid_set ||
- (wpa_s->mlme.state ==
- IEEE80211_IBSS_JOINED &&
- !ieee80211_sta_active_ibss(wpa_s)))
- ieee80211_sta_find_ibss(wpa_s);
- }
- return;
- }
- skip = !(wpa_s->mlme.hw_modes & (1 << mode->mode));
- chan = &mode->channels[wpa_s->mlme.scan_channel_idx];
- if ((chan->flag & HOSTAPD_CHAN_DISABLED) ||
- (adhoc && (chan->flag & HOSTAPD_CHAN_NO_IBSS)) ||
- (wpa_s->mlme.hw_modes & (1 << HOSTAPD_MODE_IEEE80211G) &&
- mode->mode == HOSTAPD_MODE_IEEE80211B &&
- wpa_s->mlme.scan_skip_11b))
- skip = 1;
- if (!skip && wpa_s->mlme.scan_freqs) {
- int i, found = 0;
- for (i = 0; wpa_s->mlme.scan_freqs[i]; i++) {
- if (wpa_s->mlme.scan_freqs[i] == chan->freq) {
- found = 1;
- break;
- }
- }
- if (!found)
- skip = 1;
- }
-
- if (!skip) {
- wpa_printf(MSG_MSGDUMP,
- "MLME: scan channel %d (%d MHz)",
- chan->chan, chan->freq);
-
- wpa_s->mlme.channel = chan->chan;
- wpa_s->mlme.freq = chan->freq;
- wpa_s->mlme.phymode = mode->mode;
- if (ieee80211_sta_set_channel(wpa_s, mode->mode,
- chan->chan, chan->freq))
- {
- wpa_printf(MSG_DEBUG, "MLME: failed to set "
- "channel %d (%d MHz) for scan",
- chan->chan, chan->freq);
- skip = 1;
- }
- }
-
- wpa_s->mlme.scan_channel_idx++;
- if (wpa_s->mlme.scan_channel_idx >=
- wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx].
- num_channels) {
- wpa_s->mlme.scan_hw_mode_idx++;
- wpa_s->mlme.scan_channel_idx = 0;
- }
-
- if (skip) {
- timeout = 0;
- break;
- }
-
- timeout = IEEE80211_PROBE_DELAY;
- wpa_s->mlme.scan_state = SCAN_SEND_PROBE;
- break;
- case SCAN_SEND_PROBE:
- if (ieee80211_active_scan(wpa_s)) {
- ieee80211_send_probe_req(wpa_s, NULL,
- wpa_s->mlme.scan_ssid,
- wpa_s->mlme.scan_ssid_len);
- timeout = IEEE80211_CHANNEL_TIME;
- } else {
- timeout = IEEE80211_PASSIVE_CHANNEL_TIME;
- }
- wpa_s->mlme.scan_state = SCAN_SET_CHANNEL;
- break;
- }
-
- eloop_register_timeout(timeout / 1000, 1000 * (timeout % 1000),
- ieee80211_sta_scan_timer, wpa_s, NULL);
-}
-
-
-int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- const u8 *ssid = params->ssids[0].ssid;
- size_t ssid_len = params->ssids[0].ssid_len;
-
- if (ssid_len > MAX_SSID_LEN)
- return -1;
-
- /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
- * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
- * BSSID: MACAddress
- * SSID
- * ScanType: ACTIVE, PASSIVE
- * ProbeDelay: delay (in microseconds) to be used prior to transmitting
- * a Probe frame during active scanning
- * ChannelList
- * MinChannelTime (>= ProbeDelay), in TU
- * MaxChannelTime: (>= MinChannelTime), in TU
- */
-
- /* MLME-SCAN.confirm
- * BSSDescriptionSet
- * ResultCode: SUCCESS, INVALID_PARAMETERS
- */
-
- /* TODO: if assoc, move to power save mode for the duration of the
- * scan */
-
- if (wpa_s->mlme.sta_scanning)
- return -1;
-
- wpa_printf(MSG_DEBUG, "MLME: starting scan");
-
- ieee80211_sta_set_probe_req_ie(wpa_s, params->extra_ies,
- params->extra_ies_len);
-
- os_free(wpa_s->mlme.scan_freqs);
- if (params->freqs) {
- int i;
- for (i = 0; params->freqs[i]; i++)
- ;
- wpa_s->mlme.scan_freqs = os_malloc((i + 1) * sizeof(int));
- if (wpa_s->mlme.scan_freqs)
- os_memcpy(wpa_s->mlme.scan_freqs, params->freqs,
- (i + 1) * sizeof(int));
- } else
- wpa_s->mlme.scan_freqs = NULL;
-
- ieee80211_sta_save_oper_chan(wpa_s);
-
- wpa_s->mlme.sta_scanning = 1;
- /* TODO: stop TX queue? */
-
- if (ssid) {
- wpa_s->mlme.scan_ssid_len = ssid_len;
- os_memcpy(wpa_s->mlme.scan_ssid, ssid, ssid_len);
- } else
- wpa_s->mlme.scan_ssid_len = 0;
- wpa_s->mlme.scan_skip_11b = 1; /* FIX: clear this is 11g is not
- * supported */
- wpa_s->mlme.scan_state = SCAN_SET_CHANNEL;
- wpa_s->mlme.scan_hw_mode_idx = 0;
- wpa_s->mlme.scan_channel_idx = 0;
- eloop_register_timeout(0, 1, ieee80211_sta_scan_timer, wpa_s, NULL);
-
- return 0;
-}
-
-
-struct wpa_scan_results *
-ieee80211_sta_get_scan_results(struct wpa_supplicant *wpa_s)
-{
- size_t ap_num = 0;
- struct wpa_scan_results *res;
- struct wpa_scan_res *r;
- struct ieee80211_sta_bss *bss;
-
- res = os_zalloc(sizeof(*res));
- for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next)
- ap_num++;
- res->res = os_zalloc(ap_num * sizeof(struct wpa_scan_res *));
- if (res->res == NULL) {
- os_free(res);
- return NULL;
- }
-
- for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) {
- r = os_zalloc(sizeof(*r) + bss->ie_len);
- if (r == NULL)
- break;
- os_memcpy(r->bssid, bss->bssid, ETH_ALEN);
- r->freq = bss->freq;
- r->beacon_int = bss->beacon_int;
- r->caps = bss->capability;
- r->level = bss->rssi;
- r->tsf = bss->timestamp;
- if (bss->ie) {
- r->ie_len = bss->ie_len;
- os_memcpy(r + 1, bss->ie, bss->ie_len);
- }
-
- res->res[res->num++] = r;
- }
-
- return res;
-}
-
-
-#if 0 /* FIX */
-struct sta_info * ieee80211_ibss_add_sta(struct wpa_supplicant *wpa_s,
- struct sk_buff *skb, u8 *bssid,
- u8 *addr)
-{
- struct ieee80211_local *local = dev->priv;
- struct list_head *ptr;
- struct sta_info *sta;
- struct wpa_supplicant *sta_dev = NULL;
-
- /* TODO: Could consider removing the least recently used entry and
- * allow new one to be added. */
- if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
- if (net_ratelimit()) {
- wpa_printf(MSG_DEBUG, "MLME: No room for a new IBSS "
- "STA entry " MACSTR, MAC2STR(addr));
- }
- return NULL;
- }
-
- spin_lock_bh(&local->sub_if_lock);
- list_for_each(ptr, &local->sub_if_list) {
- sdata = list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA &&
- os_memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
- sta_dev = sdata->dev;
- break;
- }
- }
- spin_unlock_bh(&local->sub_if_lock);
-
- if (sta_dev == NULL)
- return NULL;
-
- wpa_printf(MSG_DEBUG, "MLME: Adding new IBSS station " MACSTR
- " (dev=%s)", MAC2STR(addr), sta_dev->name);
-
- sta = sta_info_add(wpa_s, addr);
- if (sta == NULL) {
- return NULL;
- }
-
- sta->dev = sta_dev;
- sta->supp_rates = wpa_s->mlme.supp_rates_bits;
-
- rate_control_rate_init(local, sta);
-
- return sta; /* caller will call sta_info_release() */
-}
-#endif
-
-
-int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason)
-{
- wpa_printf(MSG_DEBUG, "MLME: deauthenticate(reason=%d)", reason);
-
- ieee80211_send_deauth(wpa_s, reason);
- ieee80211_set_associated(wpa_s, 0);
- return 0;
-}
-
-
-int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason)
-{
- wpa_printf(MSG_DEBUG, "MLME: disassociate(reason=%d)", reason);
-
- if (!wpa_s->mlme.associated)
- return -1;
-
- ieee80211_send_disassoc(wpa_s, reason);
- ieee80211_set_associated(wpa_s, 0);
- return 0;
-}
-
-
-void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len,
- struct ieee80211_rx_status *rx_status)
-{
- struct ieee80211_mgmt *mgmt;
- u16 fc;
- const u8 *pos;
-
- /* wpa_hexdump(MSG_MSGDUMP, "MLME: Received frame", buf, len); */
-
- if (wpa_s->mlme.sta_scanning) {
- ieee80211_sta_rx_scan(wpa_s, buf, len, rx_status);
- return;
- }
-
- if (len < 24)
- return;
-
- mgmt = (struct ieee80211_mgmt *) buf;
- fc = le_to_host16(mgmt->frame_control);
-
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
- ieee80211_sta_rx_mgmt(wpa_s, buf, len, rx_status);
- else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
- if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) !=
- WLAN_FC_FROMDS)
- return;
- /* mgmt->sa is actually BSSID for FromDS data frames */
- if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0)
- return;
- /* Skip IEEE 802.11 and LLC headers */
- pos = buf + 24 + 6;
- if (WPA_GET_BE16(pos) != ETH_P_EAPOL)
- return;
- pos += 2;
- /* mgmt->bssid is actually BSSID for SA data frames */
- wpa_supplicant_rx_eapol(wpa_s, mgmt->bssid,
- pos, buf + len - pos);
- }
-}
-
-
-int ieee80211_sta_init(struct wpa_supplicant *wpa_s)
-{
- u16 num_modes, flags;
-
- wpa_s->mlme.modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes,
- &flags);
- if (wpa_s->mlme.modes == NULL) {
- wpa_printf(MSG_ERROR, "MLME: Failed to read supported "
- "channels and rates from the driver");
- return -1;
- }
-
- wpa_s->mlme.num_modes = num_modes;
-
- wpa_s->mlme.hw_modes = 1 << HOSTAPD_MODE_IEEE80211A;
- wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211B;
- wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211G;
-
- wpa_s->mlme.wmm_enabled = 1;
-
- return 0;
-}
-
-
-void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s)
-{
- eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL);
- eloop_cancel_timeout(ieee80211_sta_scan_timer, wpa_s, NULL);
- os_free(wpa_s->mlme.extra_ie);
- wpa_s->mlme.extra_ie = NULL;
- os_free(wpa_s->mlme.extra_probe_ie);
- wpa_s->mlme.extra_probe_ie = NULL;
- os_free(wpa_s->mlme.assocreq_ies);
- wpa_s->mlme.assocreq_ies = NULL;
- os_free(wpa_s->mlme.assocresp_ies);
- wpa_s->mlme.assocresp_ies = NULL;
- ieee80211_bss_list_deinit(wpa_s);
- ieee80211_sta_free_hw_features(wpa_s->mlme.modes,
- wpa_s->mlme.num_modes);
-#ifdef CONFIG_IEEE80211R
- os_free(wpa_s->mlme.ft_ies);
- wpa_s->mlme.ft_ies = NULL;
- wpa_s->mlme.ft_ies_len = 0;
-#endif /* CONFIG_IEEE80211R */
-
- os_free(wpa_s->mlme.scan_freqs);
- wpa_s->mlme.scan_freqs = NULL;
-}
-
-
-#ifdef CONFIG_IEEE80211R
-
-int ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
- const u8 *ies, size_t ies_len)
-{
- if (md == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: Clear FT mobility domain");
- os_memset(wpa_s->mlme.current_md, 0, MOBILITY_DOMAIN_ID_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "MLME: Update FT IEs for MD " MACSTR,
- MAC2STR(md));
- os_memcpy(wpa_s->mlme.current_md, md, MOBILITY_DOMAIN_ID_LEN);
- }
-
- wpa_hexdump(MSG_DEBUG, "MLME: FT IEs", ies, ies_len);
- os_free(wpa_s->mlme.ft_ies);
- wpa_s->mlme.ft_ies = os_malloc(ies_len);
- if (wpa_s->mlme.ft_ies == NULL)
- return -1;
- os_memcpy(wpa_s->mlme.ft_ies, ies, ies_len);
- wpa_s->mlme.ft_ies_len = ies_len;
-
- return 0;
-}
-
-
-int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action,
- const u8 *target_ap,
- const u8 *ies, size_t ies_len)
-{
- u8 *buf;
- size_t len;
- struct ieee80211_mgmt *mgmt;
- int res;
-
- /*
- * Action frame payload:
- * Category[1] = 6 (Fast BSS Transition)
- * Action[1] = 1 (Fast BSS Transition Request)
- * STA Address
- * Target AP Address
- * FT IEs
- */
-
- buf = os_zalloc(sizeof(*mgmt) + ies_len);
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
- "FT action frame");
- return -1;
- }
-
- mgmt = (struct ieee80211_mgmt *) buf;
- len = 24;
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_ACTION);
- mgmt->u.action.category = WLAN_ACTION_FT;
- mgmt->u.action.u.ft_action_req.action = action;
- os_memcpy(mgmt->u.action.u.ft_action_req.sta_addr, wpa_s->own_addr,
- ETH_ALEN);
- os_memcpy(mgmt->u.action.u.ft_action_req.target_ap_addr, target_ap,
- ETH_ALEN);
- os_memcpy(mgmt->u.action.u.ft_action_req.variable, ies, ies_len);
- len += 1 + sizeof(mgmt->u.action.u.ft_action_req) + ies_len;
-
- wpa_printf(MSG_DEBUG, "MLME: Send FT Action Frame: Action=%d "
- "Target AP=" MACSTR " body_len=%lu",
- action, MAC2STR(target_ap), (unsigned long) ies_len);
-
- res = ieee80211_sta_tx(wpa_s, buf, len);
- os_free(buf);
-
- return res;
-}
-
-#endif /* CONFIG_IEEE80211R */
-
-
-static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len)
-{
- os_free(wpa_s->mlme.extra_probe_ie);
- wpa_s->mlme.extra_probe_ie = NULL;
- wpa_s->mlme.extra_probe_ie_len = 0;
-
- if (ies == NULL)
- return 0;
-
- wpa_s->mlme.extra_probe_ie = os_malloc(ies_len);
- if (wpa_s->mlme.extra_probe_ie == NULL)
- return -1;
-
- os_memcpy(wpa_s->mlme.extra_probe_ie, ies, ies_len);
- wpa_s->mlme.extra_probe_ie_len = ies_len;
-
- return 0;
-}
diff --git a/wpa_supplicant/mlme.h b/wpa_supplicant/mlme.h
deleted file mode 100644
index fe3c6e4..0000000
--- a/wpa_supplicant/mlme.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * WPA Supplicant - Client mode MLME
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004, Instant802 Networks, Inc.
- * Copyright (c) 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef MLME_H
-#define MLME_H
-
-struct wpa_supplicant;
-
-struct ieee80211_rx_status {
- int freq;
- int channel;
- int ssi;
-};
-
-#ifdef CONFIG_CLIENT_MLME
-
-int ieee80211_sta_init(struct wpa_supplicant *wpa_s);
-void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s);
-int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params);
-int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason);
-int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason);
-int ieee80211_sta_associate(struct wpa_supplicant *wpa_s,
- struct wpa_driver_associate_params *params);
-int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid,
- size_t *len);
-void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len,
- struct ieee80211_rx_status *rx_status);
-struct wpa_scan_results *
-ieee80211_sta_get_scan_results(struct wpa_supplicant *wpa_s);
-int ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
- const u8 *ies, size_t ies_len);
-int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action,
- const u8 *target_ap,
- const u8 *ies, size_t ies_len);
-
-#else /* CONFIG_CLIENT_MLME */
-
-static inline int ieee80211_sta_init(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- return -1;
-}
-
-static inline int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s,
- u16 reason)
-{
- return -1;
-}
-
-static inline int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s,
- u16 reason)
-{
- return -1;
-}
-
-static inline int
-ieee80211_sta_associate(struct wpa_supplicant *wpa_s,
- struct wpa_driver_associate_params *params)
-{
- return -1;
-}
-
-static inline int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s,
- u8 *ssid, size_t *len)
-{
- return -1;
-}
-
-static inline void
-ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len,
- struct ieee80211_rx_status *rx_status)
-{
-}
-
-static inline struct wpa_scan_results *
-ieee80211_sta_get_scan_results(struct wpa_supplicant *wpa_s)
-{
- return NULL;
-}
-
-static inline int
-ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
- const u8 *ies, size_t ies_len)
-{
- return -1;
-}
-
-static inline int
-ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action,
- const u8 *target_ap,
- const u8 *ies, size_t ies_len)
-{
- return -1;
-}
-
-#endif /* CONFIG_CLIENT_MLME */
-
-#endif /* MLME_H */
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 0d2f542..6e9b5a9 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -22,6 +22,7 @@
#include "dbus/dbus_common.h"
#include "dbus/dbus_old.h"
#include "dbus/dbus_new.h"
+#include "rsn_supp/wpa.h"
#include "driver_i.h"
#include "scan.h"
#include "p2p_supplicant.h"
@@ -140,6 +141,15 @@ void wpas_notify_network_selected(struct wpa_supplicant *wpa_s,
}
+void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype,
+ const char *default_txt)
+{
+ wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
+}
+
+
void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
{
/* notify the old DBus API */
@@ -238,8 +248,13 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
+ if (wpa_s->wpa)
+ wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
if (wpa_s->global->p2p_group_formation != wpa_s)
wpas_dbus_unregister_network(wpa_s, ssid->id);
+#ifdef CONFIG_P2P
+ wpas_p2p_network_removed(wpa_s, ssid);
+#endif /* CONFIG_P2P */
}
@@ -431,9 +446,10 @@ void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
}
-void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s, int status)
+void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
+ struct p2p_go_neg_results *res)
{
- wpas_dbus_signal_p2p_go_neg_resp(wpa_s, status);
+ wpas_dbus_signal_p2p_go_neg_resp(wpa_s, res);
}
@@ -509,9 +525,12 @@ void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *sta)
+ const u8 *sta,
+ const u8 *p2p_dev_addr)
{
#ifdef CONFIG_P2P
+ wpas_p2p_notify_ap_sta_authorized(wpa_s, p2p_dev_addr);
+
/*
* Register a group member object corresponding to this peer and
* emit a PeerJoined signal. This will check if it really is a
@@ -548,10 +567,11 @@ static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *mac_addr, int authorized)
+ const u8 *mac_addr, int authorized,
+ const u8 *p2p_dev_addr)
{
if (authorized)
- wpas_notify_ap_sta_authorized(wpa_s, mac_addr);
+ wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr);
else
wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr);
}
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 98cbcb1..236a31e 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -36,6 +36,10 @@ void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
void wpas_notify_network_selected(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
+void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ enum wpa_ctrl_req_type rtype,
+ const char *default_txt);
void wpas_notify_scanning(struct wpa_supplicant *wpa_s);
void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success);
void wpas_notify_scan_results(struct wpa_supplicant *wpa_s);
@@ -82,7 +86,8 @@ void wpas_notify_suspend(struct wpa_global *global);
void wpas_notify_resume(struct wpa_global *global);
void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *mac_addr, int authorized);
+ const u8 *mac_addr, int authorized,
+ const u8 *p2p_dev_addr);
void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
const u8 *dev_addr, int new_device);
void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
@@ -93,7 +98,7 @@ void wpas_notify_p2p_group_removed(struct wpa_supplicant *wpa_s,
void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
const u8 *src, u16 dev_passwd_id);
void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
- int status);
+ struct p2p_go_neg_results *res);
void wpas_notify_p2p_invitation_result(struct wpa_supplicant *wpa_s,
int status, const u8 *bssid);
void wpas_notify_p2p_sd_request(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c
new file mode 100644
index 0000000..790f14a
--- /dev/null
+++ b/wpa_supplicant/offchannel.c
@@ -0,0 +1,314 @@
+/*
+ * wpa_supplicant - Off-channel Action frame TX/RX
+ * Copyright (c) 2009-2010, Atheros Communications
+ * Copyright (c) 2011, Qualcomm Atheros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "utils/eloop.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+#include "offchannel.h"
+
+
+
+static struct wpa_supplicant *
+wpas_get_tx_interface(struct wpa_supplicant *wpa_s, const u8 *src)
+{
+ struct wpa_supplicant *iface;
+
+ if (os_memcmp(src, wpa_s->own_addr, ETH_ALEN) == 0)
+ return wpa_s;
+
+ /*
+ * Try to find a group interface that matches with the source address.
+ */
+ iface = wpa_s->global->ifaces;
+ while (iface) {
+ if (os_memcmp(wpa_s->pending_action_src,
+ iface->own_addr, ETH_ALEN) == 0)
+ break;
+ iface = iface->next;
+ }
+ if (iface) {
+ wpa_printf(MSG_DEBUG, "P2P: Use group interface %s "
+ "instead of interface %s for Action TX",
+ iface->ifname, wpa_s->ifname);
+ return iface;
+ }
+
+ return wpa_s;
+}
+
+
+static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct wpa_supplicant *iface;
+ int res;
+ int without_roc;
+
+ without_roc = wpa_s->pending_action_without_roc;
+ wpa_s->pending_action_without_roc = 0;
+ wpa_printf(MSG_DEBUG, "Off-channel: Send Action callback "
+ "(without_roc=%d pending_action_tx=%p)",
+ without_roc, wpa_s->pending_action_tx);
+
+ if (wpa_s->pending_action_tx == NULL)
+ return;
+
+ /*
+ * This call is likely going to be on the P2P device instance if the
+ * driver uses a separate interface for that purpose. However, some
+ * Action frames are actually sent within a P2P Group and when that is
+ * the case, we need to follow power saving (e.g., GO buffering the
+ * frame for a client in PS mode or a client following the advertised
+ * NoA from its GO). To make that easier for the driver, select the
+ * correct group interface here.
+ */
+ iface = wpas_get_tx_interface(wpa_s, wpa_s->pending_action_src);
+
+ if (wpa_s->off_channel_freq != wpa_s->pending_action_freq &&
+ wpa_s->pending_action_freq != 0 &&
+ wpa_s->pending_action_freq != iface->assoc_freq) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Pending Action frame TX "
+ "waiting for another freq=%u (off_channel_freq=%u "
+ "assoc_freq=%u)",
+ wpa_s->pending_action_freq,
+ wpa_s->off_channel_freq,
+ iface->assoc_freq);
+ if (without_roc && wpa_s->off_channel_freq == 0) {
+ /*
+ * We may get here if wpas_send_action() found us to be
+ * on the correct channel, but remain-on-channel cancel
+ * event was received before getting here.
+ */
+ wpa_printf(MSG_DEBUG, "Off-channel: Schedule "
+ "remain-on-channel to send Action frame");
+ if (wpa_drv_remain_on_channel(
+ wpa_s, wpa_s->pending_action_freq, 200) <
+ 0) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Failed to "
+ "request driver to remain on "
+ "channel (%u MHz) for Action Frame "
+ "TX", wpa_s->pending_action_freq);
+ } else {
+ wpa_s->off_channel_freq = 0;
+ wpa_s->roc_waiting_drv_freq =
+ wpa_s->pending_action_freq;
+ }
+ }
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "Off-channel: Sending pending Action frame to "
+ MACSTR " using interface %s",
+ MAC2STR(wpa_s->pending_action_dst), iface->ifname);
+ res = wpa_drv_send_action(iface, wpa_s->pending_action_freq, 0,
+ wpa_s->pending_action_dst,
+ wpa_s->pending_action_src,
+ wpa_s->pending_action_bssid,
+ wpabuf_head(wpa_s->pending_action_tx),
+ wpabuf_len(wpa_s->pending_action_tx),
+ wpa_s->pending_action_no_cck);
+ if (res) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Failed to send the "
+ "pending Action frame");
+ /*
+ * Use fake TX status event to allow state machines to
+ * continue.
+ */
+ offchannel_send_action_tx_status(
+ wpa_s, wpa_s->pending_action_dst,
+ wpabuf_head(wpa_s->pending_action_tx),
+ wpabuf_len(wpa_s->pending_action_tx),
+ OFFCHANNEL_SEND_ACTION_FAILED);
+ }
+}
+
+
+void offchannel_send_action_tx_status(
+ struct wpa_supplicant *wpa_s, const u8 *dst, const u8 *data,
+ size_t data_len, enum offchannel_send_action_result result)
+{
+ if (wpa_s->pending_action_tx == NULL) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Ignore Action TX status - "
+ "no pending operation");
+ return;
+ }
+
+ if (os_memcmp(dst, wpa_s->pending_action_dst, ETH_ALEN) != 0) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Ignore Action TX status - "
+ "unknown destination address");
+ return;
+ }
+
+ wpabuf_free(wpa_s->pending_action_tx);
+ wpa_s->pending_action_tx = NULL;
+
+ wpa_printf(MSG_DEBUG, "Off-channel: TX status result=%d cb=%p",
+ result, wpa_s->pending_action_tx_status_cb);
+
+ if (wpa_s->pending_action_tx_status_cb) {
+ wpa_s->pending_action_tx_status_cb(
+ wpa_s, wpa_s->pending_action_freq,
+ wpa_s->pending_action_dst, wpa_s->pending_action_src,
+ wpa_s->pending_action_bssid,
+ data, data_len, result);
+ }
+}
+
+
+int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
+ const u8 *dst, const u8 *src, const u8 *bssid,
+ const u8 *buf, size_t len, unsigned int wait_time,
+ void (*tx_cb)(struct wpa_supplicant *wpa_s,
+ unsigned int freq, const u8 *dst,
+ const u8 *src, const u8 *bssid,
+ const u8 *data, size_t data_len,
+ enum offchannel_send_action_result
+ result),
+ int no_cck)
+{
+ wpa_printf(MSG_DEBUG, "Off-channel: Send action frame: freq=%d dst="
+ MACSTR " src=" MACSTR " bssid=" MACSTR " len=%d",
+ freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
+ (int) len);
+
+ wpa_s->pending_action_tx_status_cb = tx_cb;
+
+ if (wpa_s->pending_action_tx) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Dropped pending Action "
+ "frame TX to " MACSTR,
+ MAC2STR(wpa_s->pending_action_dst));
+ wpabuf_free(wpa_s->pending_action_tx);
+ }
+ wpa_s->pending_action_tx = wpabuf_alloc(len);
+ if (wpa_s->pending_action_tx == NULL) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Failed to allocate Action "
+ "frame TX buffer (len=%llu)",
+ (unsigned long long) len);
+ return -1;
+ }
+ wpabuf_put_data(wpa_s->pending_action_tx, buf, len);
+ os_memcpy(wpa_s->pending_action_src, src, ETH_ALEN);
+ os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN);
+ os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN);
+ wpa_s->pending_action_freq = freq;
+ wpa_s->pending_action_no_cck = no_cck;
+
+ if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
+ struct wpa_supplicant *iface;
+
+ iface = wpas_get_tx_interface(wpa_s,
+ wpa_s->pending_action_src);
+ wpa_s->action_tx_wait_time = wait_time;
+
+ return wpa_drv_send_action(
+ iface, wpa_s->pending_action_freq,
+ wait_time, wpa_s->pending_action_dst,
+ wpa_s->pending_action_src, wpa_s->pending_action_bssid,
+ wpabuf_head(wpa_s->pending_action_tx),
+ wpabuf_len(wpa_s->pending_action_tx),
+ wpa_s->pending_action_no_cck);
+ }
+
+ if (freq) {
+ struct wpa_supplicant *tx_iface;
+ tx_iface = wpas_get_tx_interface(wpa_s, src);
+ if (tx_iface->assoc_freq == freq) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Already on "
+ "requested channel (TX interface operating "
+ "channel)");
+ freq = 0;
+ }
+ }
+
+ if (wpa_s->off_channel_freq == freq || freq == 0) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Already on requested "
+ "channel; send Action frame immediately");
+ /* TODO: Would there ever be need to extend the current
+ * duration on the channel? */
+ wpa_s->pending_action_without_roc = 1;
+ eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
+ eloop_register_timeout(0, 0, wpas_send_action_cb, wpa_s, NULL);
+ return 0;
+ }
+ wpa_s->pending_action_without_roc = 0;
+
+ if (wpa_s->roc_waiting_drv_freq == freq) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Already waiting for "
+ "driver to get to frequency %u MHz; continue "
+ "waiting to send the Action frame", freq);
+ return 0;
+ }
+
+ wpa_printf(MSG_DEBUG, "Off-channel: Schedule Action frame to be "
+ "transmitted once the driver gets to the requested "
+ "channel");
+ if (wait_time > wpa_s->max_remain_on_chan)
+ wait_time = wpa_s->max_remain_on_chan;
+ if (wpa_drv_remain_on_channel(wpa_s, freq, wait_time) < 0) {
+ wpa_printf(MSG_DEBUG, "Off-channel: Failed to request driver "
+ "to remain on channel (%u MHz) for Action "
+ "Frame TX", freq);
+ return -1;
+ }
+ wpa_s->off_channel_freq = 0;
+ wpa_s->roc_waiting_drv_freq = freq;
+
+ return 0;
+}
+
+
+void offchannel_send_action_done(struct wpa_supplicant *wpa_s)
+{
+ wpa_printf(MSG_DEBUG, "Off-channel: Action frame sequence done "
+ "notification");
+ wpabuf_free(wpa_s->pending_action_tx);
+ wpa_s->pending_action_tx = NULL;
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX &&
+ wpa_s->action_tx_wait_time)
+ wpa_drv_send_action_cancel_wait(wpa_s);
+
+ if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
+ wpa_drv_cancel_remain_on_channel(wpa_s);
+ wpa_s->off_channel_freq = 0;
+ wpa_s->roc_waiting_drv_freq = 0;
+ }
+}
+
+
+void offchannel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq, unsigned int duration)
+{
+ wpa_s->roc_waiting_drv_freq = 0;
+ wpa_s->off_channel_freq = freq;
+ wpas_send_action_cb(wpa_s, NULL);
+}
+
+
+void offchannel_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq)
+{
+ wpa_s->off_channel_freq = 0;
+}
+
+
+void offchannel_deinit(struct wpa_supplicant *wpa_s)
+{
+ wpabuf_free(wpa_s->pending_action_tx);
+ wpa_s->pending_action_tx = NULL;
+ eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
+}
diff --git a/wpa_supplicant/offchannel.h b/wpa_supplicant/offchannel.h
new file mode 100644
index 0000000..60e0d03
--- /dev/null
+++ b/wpa_supplicant/offchannel.h
@@ -0,0 +1,39 @@
+/*
+ * wpa_supplicant - Off-channel Action frame TX/RX
+ * Copyright (c) 2009-2010, Atheros Communications
+ * Copyright (c) 2011, Qualcomm Atheros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef OFFCHANNEL_H
+#define OFFCHANNEL_H
+
+int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
+ const u8 *dst, const u8 *src, const u8 *bssid,
+ const u8 *buf, size_t len, unsigned int wait_time,
+ void (*tx_cb)(struct wpa_supplicant *wpa_s,
+ unsigned int freq, const u8 *dst,
+ const u8 *src, const u8 *bssid,
+ const u8 *data, size_t data_len,
+ enum offchannel_send_action_result
+ result),
+ int no_cck);
+void offchannel_send_action_done(struct wpa_supplicant *wpa_s);
+void offchannel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq, unsigned int duration);
+void offchannel_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq);
+void offchannel_deinit(struct wpa_supplicant *wpa_s);
+void offchannel_send_action_tx_status(
+ struct wpa_supplicant *wpa_s, const u8 *dst, const u8 *data,
+ size_t data_len, enum offchannel_send_action_result result);
+
+#endif /* OFFCHANNEL_H */
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index f4c5a53..613d37c 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -22,6 +22,7 @@
#include "wps/wps_i.h"
#include "p2p/p2p.h"
#include "ap/hostapd.h"
+#include "ap/ap_config.h"
#include "ap/p2p_hostapd.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "rsn_supp/wpa.h"
@@ -30,10 +31,10 @@
#include "ap.h"
#include "config_ssid.h"
#include "config.h"
-#include "mlme.h"
#include "notify.h"
#include "scan.h"
#include "bss.h"
+#include "offchannel.h"
#include "wps_supplicant.h"
#include "p2p_supplicant.h"
@@ -44,6 +45,14 @@
*/
#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
+#ifndef P2P_MAX_CLIENT_IDLE
+/*
+ * How many seconds to try to reconnect to the GO when connection in P2P client
+ * role has been lost.
+ */
+#define P2P_MAX_CLIENT_IDLE 10
+#endif /* P2P_MAX_CLIENT_IDLE */
+
static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
static struct wpa_supplicant *
@@ -58,6 +67,36 @@ static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
+#ifdef ANDROID_P2P
+void wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq)
+{
+ struct wpa_supplicant *iface = NULL;
+ struct p2p_data *p2p = wpa_s->global->p2p;
+
+ for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+ if((iface->p2p_group_interface) && (iface->current_ssid) &&
+ (iface->current_ssid->frequency != freq)) {
+
+ if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO) {
+ /* Try to see whether we can move the GO. If it
+ * is not possible, remove the GO interface
+ */
+ if(wpa_drv_go_switch_channel(iface, freq) == 0) {
+ wpa_printf(MSG_ERROR, "P2P: GO Moved to freq(%d)", freq);
+ iface->current_ssid->frequency = freq;
+ //p2p->op_channel = freq;
+ continue;
+ }
+ }
+
+ /* If GO cannot be moved or if the conflicting interface is a
+ * P2P Client, remove the interface */
+ wpas_p2p_disconnect(iface);
+ }
+ }
+}
+#endif
+
static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res)
@@ -92,6 +131,8 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
int ret;
struct wpabuf *wps_ie, *ies;
int social_channels[] = { 2412, 2437, 2462, 0, 0 };
+ size_t ielen;
+ int was_in_p2p_scan;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
@@ -110,7 +151,8 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
if (wps_ie == NULL)
return -1;
- ies = wpabuf_alloc(wpabuf_len(wps_ie) + 100);
+ ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
+ ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
if (ies == NULL) {
wpabuf_free(wps_ie);
return -1;
@@ -120,6 +162,7 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
p2p_scan_ie(wpa_s->global->p2p, ies);
+ params.p2p_probe = 1;
params.extra_ies = wpabuf_head(ies);
params.extra_ies_len = wpabuf_len(ies);
@@ -140,37 +183,22 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
break;
}
+ was_in_p2p_scan = wpa_s->scan_res_handler == wpas_p2p_scan_res_handler;
wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- ret = ieee80211_sta_req_scan(wpa_s, &params);
- else
- ret = wpa_drv_scan(wpa_s, &params);
+ ret = wpa_drv_scan(wpa_s, &params);
wpabuf_free(ies);
- return ret;
-}
-
-
-#ifdef CONFIG_CLIENT_MLME
-static void p2p_rx_action_mlme(void *ctx, const u8 *buf, size_t len, int freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const struct ieee80211_mgmt *mgmt;
- size_t hdr_len;
+ if (ret) {
+ wpa_s->scan_res_handler = NULL;
+ if (wpa_s->scanning || was_in_p2p_scan) {
+ wpa_s->p2p_cb_on_scan_complete = 1;
+ ret = 1;
+ }
+ }
- if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
- return;
- mgmt = (const struct ieee80211_mgmt *) buf;
- hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
- if (hdr_len > len)
- return;
- p2p_rx_action(wpa_s->global->p2p, mgmt->da, mgmt->sa, mgmt->bssid,
- mgmt->u.action.category,
- &mgmt->u.action.u.vs_public_action.action,
- len - hdr_len, freq);
+ return ret;
}
-#endif /* CONFIG_CLIENT_MLME */
static enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface)
@@ -467,6 +495,52 @@ static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
}
+static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
+ const u8 *addr)
+{
+ struct wpa_ssid *ssid, *s;
+ u8 *n;
+ size_t i;
+
+ ssid = wpa_s->current_ssid;
+ if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
+ !ssid->p2p_persistent_group)
+ return;
+
+ for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
+ if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
+ continue;
+
+ if (s->ssid_len == ssid->ssid_len &&
+ os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
+ break;
+ }
+
+ if (s == NULL)
+ return;
+
+ for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
+ if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
+ ETH_ALEN) == 0)
+ return; /* already in list */
+ }
+
+ n = os_realloc(s->p2p_client_list,
+ (s->num_p2p_clients + 1) * ETH_ALEN);
+ if (n == NULL)
+ return;
+ os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
+ s->p2p_client_list = n;
+ s->num_p2p_clients++;
+
+#ifndef CONFIG_NO_CONFIG_WRITE
+ if (wpa_s->parent->conf->update_config &&
+ wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
+ wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
+}
+
+
static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
int success)
{
@@ -509,15 +583,8 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
client = ssid->mode == WPAS_MODE_INFRA;
if (ssid->mode == WPAS_MODE_P2P_GO) {
persistent = ssid->p2p_persistent_group;
-#ifndef ANDROID_BRCM_P2P_PATCH
- os_memcpy(go_dev_addr, wpa_s->parent->own_addr,
- ETH_ALEN);
-#else
- /* P2P_ADDR: Use p2p_dev_addr instead of own mac addr */
os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
ETH_ALEN);
-
-#endif
} else
persistent = wpas_p2p_persistent_group(wpa_s,
go_dev_addr,
@@ -564,162 +631,45 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
if (persistent)
network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
ssid, go_dev_addr);
- if (network_id < 0)
+ if (network_id < 0 && ssid)
network_id = ssid->id;
if (!client)
wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
}
-static struct wpa_supplicant *
-wpas_get_tx_interface(struct wpa_supplicant *wpa_s, const u8 *src)
-{
- struct wpa_supplicant *iface;
-
- if (os_memcmp(src, wpa_s->own_addr, ETH_ALEN) == 0)
- return wpa_s;
-
- /*
- * Try to find a group interface that matches with the source address.
- */
- iface = wpa_s->global->ifaces;
- while (iface) {
- if (os_memcmp(wpa_s->pending_action_src,
- iface->own_addr, ETH_ALEN) == 0)
- break;
- iface = iface->next;
- }
- if (iface) {
- wpa_printf(MSG_DEBUG, "P2P: Use group interface %s "
- "instead of interface %s for Action TX",
- iface->ifname, wpa_s->ifname);
- return iface;
- }
-
- return wpa_s;
-}
-
-
-static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
+static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
+ unsigned int freq,
+ const u8 *dst, const u8 *src,
+ const u8 *bssid,
+ const u8 *data, size_t data_len,
+ enum offchannel_send_action_result
+ result)
{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_supplicant *iface;
- int res;
- int without_roc;
+ enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS;
- without_roc = wpa_s->pending_action_without_roc;
- wpa_s->pending_action_without_roc = 0;
- wpa_printf(MSG_DEBUG, "P2P: Send Action callback (without_roc=%d "
- "pending_action_tx=%p)",
- without_roc, wpa_s->pending_action_tx);
-
- if (wpa_s->pending_action_tx == NULL)
- return;
-
- /*
- * This call is likely going to be on the P2P device instance if the
- * driver uses a separate interface for that purpose. However, some
- * Action frames are actually sent within a P2P Group and when that is
- * the case, we need to follow power saving (e.g., GO buffering the
- * frame for a client in PS mode or a client following the advertised
- * NoA from its GO). To make that easier for the driver, select the
- * correct group interface here.
- */
- iface = wpas_get_tx_interface(wpa_s, wpa_s->pending_action_src);
-
- if (wpa_s->off_channel_freq != wpa_s->pending_action_freq &&
- wpa_s->pending_action_freq != 0 &&
- wpa_s->pending_action_freq != iface->assoc_freq) {
- wpa_printf(MSG_DEBUG, "P2P: Pending Action frame TX "
- "waiting for another freq=%u (off_channel_freq=%u "
- "assoc_freq=%u)",
- wpa_s->pending_action_freq,
- wpa_s->off_channel_freq,
- iface->assoc_freq);
- if (without_roc && wpa_s->off_channel_freq == 0) {
- /*
- * We may get here if wpas_send_action() found us to be
- * on the correct channel, but remain-on-channel cancel
- * event was received before getting here.
- */
- wpa_printf(MSG_DEBUG, "P2P: Schedule "
- "remain-on-channel to send Action frame");
- if (wpa_drv_remain_on_channel(
- wpa_s, wpa_s->pending_action_freq, 200) <
- 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to request "
- "driver to remain on channel (%u "
- "MHz) for Action Frame TX",
- wpa_s->pending_action_freq);
- } else {
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq =
- wpa_s->pending_action_freq;
- }
- }
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Sending pending Action frame to "
- MACSTR " using interface %s",
- MAC2STR(wpa_s->pending_action_dst), iface->ifname);
- res = wpa_drv_send_action(iface, wpa_s->pending_action_freq, 0,
- wpa_s->pending_action_dst,
- wpa_s->pending_action_src,
- wpa_s->pending_action_bssid,
- wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx));
- if (res) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to send the pending "
- "Action frame");
- /*
- * Use fake TX status event to allow P2P state machine to
- * continue.
- */
- wpas_send_action_tx_status(
- wpa_s, wpa_s->pending_action_dst,
- wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx),
- P2P_SEND_ACTION_FAILED);
- }
-}
-
-
-void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
- const u8 *data, size_t data_len,
- enum p2p_send_action_result result)
-{
if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
return;
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
return;
- if (wpa_s->pending_action_tx == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore Action TX status - no "
- "pending operation");
- return;
- }
-
- if (os_memcmp(dst, wpa_s->pending_action_dst, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore Action TX status - unknown "
- "destination address");
- return;
+ switch (result) {
+ case OFFCHANNEL_SEND_ACTION_SUCCESS:
+ res = P2P_SEND_ACTION_SUCCESS;
+ break;
+ case OFFCHANNEL_SEND_ACTION_NO_ACK:
+ res = P2P_SEND_ACTION_NO_ACK;
+ break;
+ case OFFCHANNEL_SEND_ACTION_FAILED:
+ res = P2P_SEND_ACTION_FAILED;
+ break;
}
- wpabuf_free(wpa_s->pending_action_tx);
- wpa_s->pending_action_tx = NULL;
-
- p2p_send_action_cb(wpa_s->global->p2p, wpa_s->pending_action_freq,
- wpa_s->pending_action_dst,
- wpa_s->pending_action_src,
- wpa_s->pending_action_bssid,
- result);
+ p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
if (wpa_s->pending_pd_before_join &&
- (os_memcmp(wpa_s->pending_action_dst, wpa_s->pending_join_dev_addr,
- ETH_ALEN) == 0 ||
- os_memcmp(wpa_s->pending_action_dst,
- wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
+ (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
+ os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
wpa_s->pending_pd_before_join = 0;
wpa_printf(MSG_DEBUG, "P2P: Starting pending "
"join-existing-group operation");
@@ -733,104 +683,16 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
size_t len, unsigned int wait_time)
{
struct wpa_supplicant *wpa_s = ctx;
-
- wpa_printf(MSG_DEBUG, "P2P: Send action frame: freq=%d dst=" MACSTR
- " src=" MACSTR " bssid=" MACSTR " len=%d",
- freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
- (int) len);
-
- if (wpa_s->pending_action_tx) {
- wpa_printf(MSG_DEBUG, "P2P: Dropped pending Action frame TX "
- "to " MACSTR, MAC2STR(wpa_s->pending_action_dst));
- wpabuf_free(wpa_s->pending_action_tx);
- }
- wpa_s->pending_action_tx = wpabuf_alloc(len);
- if (wpa_s->pending_action_tx == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to allocate Action frame "
- "TX buffer (len=%llu)", (unsigned long long) len);
- return -1;
- }
- wpabuf_put_data(wpa_s->pending_action_tx, buf, len);
- os_memcpy(wpa_s->pending_action_src, src, ETH_ALEN);
- os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN);
- os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN);
- wpa_s->pending_action_freq = freq;
-
- if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
- struct wpa_supplicant *iface;
-
- iface = wpas_get_tx_interface(wpa_s, wpa_s->pending_action_src);
- wpa_s->action_tx_wait_time = wait_time;
-
- return wpa_drv_send_action(iface, wpa_s->pending_action_freq,
- wait_time, wpa_s->pending_action_dst,
- wpa_s->pending_action_src,
- wpa_s->pending_action_bssid,
- wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx));
- }
-
- if (freq) {
- struct wpa_supplicant *tx_iface;
- tx_iface = wpas_get_tx_interface(wpa_s, src);
- if (tx_iface->assoc_freq == freq) {
- wpa_printf(MSG_DEBUG, "P2P: Already on requested "
- "channel (TX interface operating channel)");
- freq = 0;
- }
- }
-
- if (wpa_s->off_channel_freq == freq || freq == 0) {
- wpa_printf(MSG_DEBUG, "P2P: Already on requested channel; "
- "send Action frame immediately");
- /* TODO: Would there ever be need to extend the current
- * duration on the channel? */
- wpa_s->pending_action_without_roc = 1;
- eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
- eloop_register_timeout(0, 0, wpas_send_action_cb, wpa_s, NULL);
- return 0;
- }
- wpa_s->pending_action_without_roc = 0;
-
- if (wpa_s->roc_waiting_drv_freq == freq) {
- wpa_printf(MSG_DEBUG, "P2P: Already waiting for driver to get "
- "to frequency %u MHz; continue waiting to send the "
- "Action frame", freq);
- return 0;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Schedule Action frame to be transmitted "
- "once the driver gets to the requested channel");
- if (wait_time > wpa_s->max_remain_on_chan)
- wait_time = wpa_s->max_remain_on_chan;
- if (wpa_drv_remain_on_channel(wpa_s, freq, wait_time) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to request driver "
- "to remain on channel (%u MHz) for Action "
- "Frame TX", freq);
- return -1;
- }
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = freq;
-
- return 0;
+ return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
+ wait_time,
+ wpas_p2p_send_action_tx_status, 1);
}
static void wpas_send_action_done(void *ctx)
{
struct wpa_supplicant *wpa_s = ctx;
- wpa_printf(MSG_DEBUG, "P2P: Action frame sequence done notification");
- wpabuf_free(wpa_s->pending_action_tx);
- wpa_s->pending_action_tx = NULL;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
- if (wpa_s->action_tx_wait_time)
- wpa_drv_send_action_cancel_wait(wpa_s);
- wpa_s->off_channel_freq = 0;
- } else if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
- wpa_drv_cancel_remain_on_channel(wpa_s);
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = 0;
- }
+ offchannel_send_action_done(wpa_s);
}
@@ -887,22 +749,13 @@ static void p2p_go_configured(void *ctx, void *data)
wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->frequency,
params->passphrase ? params->passphrase : "",
-#ifndef ANDROID_BRCM_P2P_PATCH
- MAC2STR(wpa_s->parent->own_addr),
-#else
- /* P2P_ADDR: use p2p_dev_addr instead of own addr */
MAC2STR(wpa_s->global->p2p_dev_addr),
-#endif
params->persistent_group ? " [PERSISTENT]" : "");
+
if (params->persistent_group)
network_id = wpas_p2p_store_persistent_group(
wpa_s->parent, ssid,
-#ifndef ANDROID_BRCM_P2P_PATCH
- wpa_s->parent->own_addr);
-#else
- /* P2P_ADDR: Use p2p device address */
wpa_s->global->p2p_dev_addr);
-#endif
if (network_id < 0)
network_id = ssid->id;
wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
@@ -920,7 +773,7 @@ static void p2p_go_configured(void *ctx, void *data)
}
if (params->wps_method == WPS_PBC)
wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr,
- NULL);
+ params->peer_device_addr);
else if (wpa_s->p2p_pin[0])
wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr,
wpa_s->p2p_pin, NULL, 0);
@@ -942,6 +795,8 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
if (ssid == NULL)
return;
+ wpa_s->show_group_started = 0;
+
wpa_config_set_network_defaults(ssid);
ssid->temporary = 1;
ssid->p2p_group = 1;
@@ -995,6 +850,7 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
d->p2p_group_idle = s->p2p_group_idle;
d->p2p_intra_bss = s->p2p_intra_bss;
+ d->persistent_reconnect = s->persistent_reconnect;
}
@@ -1017,16 +873,7 @@ static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
os_snprintf(ifname, sizeof(ifname), "p2p-%s-%d", wpa_s->ifname,
wpa_s->p2p_group_idx);
-
-#ifdef ANDROID_BRCM_P2P_PATCH
- /**
- * Monitor interface name is derived from p2p interface name
- * We need to reset p2p interface name early to take care of extra character in monitor interface name
- */
- if (os_strlen(ifname) + os_strlen(WPA_MONITOR_IFNAME_PREFIX) >= IFNAMSIZ &&
-#else
- if (os_strlen(ifname) >= IFNAMSIZ &&
-#endif
+ if (os_strlen(ifname) >= IFNAMSIZ &&
os_strlen(wpa_s->ifname) < IFNAMSIZ) {
/* Try to avoid going over the IFNAMSIZ length limit */
os_snprintf(ifname, sizeof(ifname), "p2p-%d",
@@ -1147,13 +994,13 @@ void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
if (res->status) {
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_FAILURE "status=%d",
res->status);
- wpas_notify_p2p_go_neg_completed(wpa_s, res->status);
+ wpas_notify_p2p_go_neg_completed(wpa_s, res);
wpas_p2p_remove_pending_group_interface(wpa_s);
return;
}
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS);
- wpas_notify_p2p_go_neg_completed(wpa_s, P2P_SC_SUCCESS);
+ wpas_notify_p2p_go_neg_completed(wpa_s, res);
if (wpa_s->create_p2p_iface) {
struct wpa_supplicant *group_wpa_s =
@@ -1209,6 +1056,7 @@ void wpas_dev_found(void *ctx, const u8 *addr,
const struct p2p_peer_info *info,
int new_device)
{
+#ifndef CONFIG_NO_STDOUT_DEBUG
struct wpa_supplicant *wpa_s = ctx;
char devtype[WPS_DEV_TYPE_BUFSIZE];
@@ -1221,6 +1069,7 @@ void wpas_dev_found(void *ctx, const u8 *addr,
sizeof(devtype)),
info->device_name, info->config_methods,
info->dev_capab, info->group_capab);
+#endif /* CONFIG_NO_STDOUT_DEBUG */
wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
}
@@ -1229,10 +1078,10 @@ void wpas_dev_found(void *ctx, const u8 *addr,
static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
{
struct wpa_supplicant *wpa_s = ctx;
-#ifdef ANDROID_BRCM_P2P_PATCH
+
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
"p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));
-#endif
+
wpas_notify_p2p_device_lost(wpa_s, dev_addr);
}
@@ -1284,7 +1133,7 @@ static void wpas_stop_listen(void *ctx)
static int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf)
{
struct wpa_supplicant *wpa_s = ctx;
- return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf));
+ return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1);
}
@@ -1579,8 +1428,11 @@ void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
os_free(buf);
}
- if (wpa_s->p2p_sd_over_ctrl_iface)
+ if (wpa_s->p2p_sd_over_ctrl_iface) {
+ wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
+ update_indic, tlvs, tlvs_len);
return; /* to be processed by an external program */
+ }
resp = wpabuf_alloc(10000);
if (resp == NULL)
@@ -1727,26 +1579,26 @@ void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
}
-void * wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *tlvs)
+u64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
+ const struct wpabuf *tlvs)
{
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
- return (void *) wpa_drv_p2p_sd_request(wpa_s, dst, tlvs);
+ return wpa_drv_p2p_sd_request(wpa_s, dst, tlvs);
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return NULL;
- return p2p_sd_request(wpa_s->global->p2p, dst, tlvs);
+ return 0;
+ return (uintptr_t) p2p_sd_request(wpa_s->global->p2p, dst, tlvs);
}
-void * wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
- u8 version, const char *query)
+u64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
+ u8 version, const char *query)
{
struct wpabuf *tlvs;
- void *ret;
+ u64 ret;
tlvs = wpabuf_alloc(2 + 1 + 1 + 1 + os_strlen(query));
if (tlvs == NULL)
- return NULL;
+ return 0;
wpabuf_put_le16(tlvs, 1 + 1 + 1 + os_strlen(query));
wpabuf_put_u8(tlvs, P2P_SERV_UPNP); /* Service Protocol Type */
wpabuf_put_u8(tlvs, 1); /* Service Transaction ID */
@@ -1758,13 +1610,14 @@ void * wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
}
-int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, void *req)
+int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req)
{
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
- return wpa_drv_p2p_sd_cancel_request(wpa_s, (u64) req);
+ return wpa_drv_p2p_sd_cancel_request(wpa_s, req);
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
- return p2p_sd_cancel_request(wpa_s->global->p2p, req);
+ return p2p_sd_cancel_request(wpa_s->global->p2p,
+ (void *) (uintptr_t) req);
}
@@ -1925,13 +1778,28 @@ static void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s,
void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
const u8 *dev_addr, const u8 *pri_dev_type,
const char *dev_name, u16 supp_config_methods,
- u8 dev_capab, u8 group_capab)
+ u8 dev_capab, u8 group_capab, const u8 *group_id,
+ size_t group_id_len)
{
struct wpa_supplicant *wpa_s = ctx;
char devtype[WPS_DEV_TYPE_BUFSIZE];
- char params[200];
+ char params[300];
u8 empty_dev_type[8];
unsigned int generated_pin = 0;
+ struct wpa_supplicant *group = NULL;
+
+ if (group_id) {
+ for (group = wpa_s->global->ifaces; group; group = group->next)
+ {
+ struct wpa_ssid *s = group->current_ssid;
+ if (s != NULL &&
+ s->mode == WPAS_MODE_P2P_GO &&
+ group_id_len - ETH_ALEN == s->ssid_len &&
+ os_memcmp(group_id + ETH_ALEN, s->ssid,
+ s->ssid_len) == 0)
+ break;
+ }
+ }
if (pri_dev_type == NULL) {
os_memset(empty_dev_type, 0, sizeof(empty_dev_type));
@@ -1939,14 +1807,19 @@ void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
}
os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR
" pri_dev_type=%s name='%s' config_methods=0x%x "
- "dev_capab=0x%x group_capab=0x%x",
+ "dev_capab=0x%x group_capab=0x%x%s%s",
MAC2STR(dev_addr),
wps_dev_type_bin2str(pri_dev_type, devtype,
sizeof(devtype)),
- dev_name, supp_config_methods, dev_capab, group_capab);
+ dev_name, supp_config_methods, dev_capab, group_capab,
+ group ? " group=" : "",
+ group ? group->ifname : "");
params[sizeof(params) - 1] = '\0';
-
+#ifdef ANDROID_P2P
+ if ((config_methods & WPS_CONFIG_DISPLAY) && (wpa_s->p2p_pin[0] == '\0')) {
+#else
if (config_methods & WPS_CONFIG_DISPLAY) {
+#endif
generated_pin = wps_generate_pin();
wpas_prov_disc_local_display(wpa_s, peer, params,
generated_pin);
@@ -1969,7 +1842,11 @@ void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
if (config_methods & WPS_CONFIG_DISPLAY)
wpas_prov_disc_local_keypad(wpa_s, peer, "");
+#ifdef ANDROID_P2P
+ else if ((config_methods & WPS_CONFIG_KEYPAD) && (wpa_s->p2p_pin[0] == '\0')) {
+#else
else if (config_methods & WPS_CONFIG_KEYPAD) {
+#endif
generated_pin = wps_generate_pin();
wpas_prov_disc_local_display(wpa_s, peer, "", generated_pin);
} else if (config_methods & WPS_CONFIG_PUSHBUTTON)
@@ -1991,8 +1868,8 @@ void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
}
-void wpas_prov_disc_fail(void *ctx, const u8 *peer,
- enum p2p_prov_disc_status status)
+static void wpas_prov_disc_fail(void *ctx, const u8 *peer,
+ enum p2p_prov_disc_status status)
{
struct wpa_supplicant *wpa_s = ctx;
@@ -2281,8 +2158,7 @@ struct p2p_oper_class_map {
static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
struct p2p_channels *chan)
{
- struct hostapd_hw_modes *modes, *mode;
- u16 num_modes, flags;
+ struct hostapd_hw_modes *mode;
int cla, op;
struct p2p_oper_class_map op_class[] = {
{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
@@ -2300,8 +2176,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
{ -1, 0, 0, 0, 0, BW20 }
};
- modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
- if (modes == NULL) {
+ if (wpa_s->hw.modes == NULL) {
wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
"of all supported channels; assume dualband "
"support");
@@ -2315,7 +2190,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
u8 ch;
struct p2p_reg_class *reg = NULL;
- mode = get_mode(modes, num_modes, o->mode);
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode);
if (mode == NULL)
continue;
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
@@ -2348,8 +2223,6 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
chan->reg_classes = cla;
- ieee80211_sta_free_hw_features(modes, num_modes);
-
return 0;
}
@@ -2381,25 +2254,10 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
struct p2p_config p2p;
unsigned int r;
int i;
-#ifdef ANDROID_BRCM_P2P_PATCH
- char buf[200];
-#endif
if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
return 0;
-#ifdef CONFIG_CLIENT_MLME
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) {
- wpa_s->mlme.public_action_cb = p2p_rx_action_mlme;
- wpa_s->mlme.public_action_cb_ctx = wpa_s;
- }
-#endif /* CONFIG_CLIENT_MLME */
-
- if (wpa_drv_disable_11b_rates(wpa_s, 1) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to disable 11b rates");
- /* Continue anyway; this is not really a fatal error */
- }
-
if (global->p2p)
return 0;
@@ -2445,20 +2303,8 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
p2p.invitation_result = wpas_invitation_result;
p2p.get_noa = wpas_get_noa;
-#ifdef ANDROID_BRCM_P2P_PATCH
- /* P2P_ADDR: Using p2p_dev_addr to hold the actual p2p device address incase if
- * we are not using the primary interface for p2p operations.
- */
- wpa_drv_driver_cmd(wpa_s, "P2P_DEV_ADDR", buf, sizeof(buf));
- os_memcpy(p2p.p2p_dev_addr, buf, ETH_ALEN);
- os_memcpy(wpa_s->global->p2p_dev_addr, buf, ETH_ALEN);
- os_memcpy(p2p.dev_addr, buf, ETH_ALEN);
- wpa_printf(MSG_DEBUG, "P2P: Device address ("MACSTR")", MAC2STR(p2p.p2p_dev_addr));
-#else
os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
-#endif
-
- os_memcpy(p2p.dev_addr, wpa_s->own_addr, ETH_ALEN);
+ os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
p2p.dev_name = wpa_s->conf->device_name;
p2p.manufacturer = wpa_s->conf->manufacturer;
p2p.model_name = wpa_s->conf->model_name;
@@ -2564,11 +2410,16 @@ void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
{
if (wpa_s->driver && wpa_s->drv_priv)
wpa_drv_probe_req_report(wpa_s, 0);
+
+ if (wpa_s->go_params) {
+ /* Clear any stored provisioning info */
+ p2p_clear_provisioning_info(
+ wpa_s->global->p2p,
+ wpa_s->go_params->peer_interface_addr);
+ }
+
os_free(wpa_s->go_params);
wpa_s->go_params = NULL;
- wpabuf_free(wpa_s->pending_action_tx);
- wpa_s->pending_action_tx = NULL;
- eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
wpa_s->p2p_long_listen = 0;
@@ -2656,6 +2507,9 @@ static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group)
{
+ if (persistent_group && wpa_s->conf->persistent_reconnect)
+ persistent_group = 2;
+
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
return wpa_drv_p2p_connect(wpa_s, peer_addr, wps_method,
go_intent, own_interface_addr,
@@ -2674,6 +2528,9 @@ static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s,
int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group)
{
+ if (persistent_group && wpa_s->conf->persistent_reconnect)
+ persistent_group = 2;
+
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
return -1;
@@ -2756,7 +2613,6 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
wpa_s->pending_pd_before_join = 1;
switch (wpa_s->pending_join_wps_method) {
- case WPS_PIN_LABEL:
case WPS_PIN_DISPLAY:
method = WPS_CONFIG_KEYPAD;
break;
@@ -2771,9 +2627,24 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
break;
}
+ if ((p2p_get_provisioning_info(wpa_s->global->p2p,
+ wpa_s->pending_join_dev_addr) ==
+ method)) {
+ /*
+ * We have already performed provision discovery for
+ * joining the group. Proceed directly to join
+ * operation without duplicated provision discovery. */
+ wpa_printf(MSG_DEBUG, "P2P: Provision discovery "
+ "with " MACSTR " already done - proceed to "
+ "join",
+ MAC2STR(wpa_s->pending_join_dev_addr));
+ wpa_s->pending_pd_before_join = 0;
+ goto start;
+ }
+
if (p2p_prov_disc_req(wpa_s->global->p2p,
- wpa_s->pending_join_dev_addr, method, 1)
- < 0) {
+ wpa_s->pending_join_dev_addr, method, 1,
+ freq) < 0) {
wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision "
"Discovery Request before joining an "
"existing group");
@@ -2806,6 +2677,7 @@ static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
int ret;
struct wpa_driver_scan_params params;
struct wpabuf *wps_ie, *ies;
+ size_t ielen;
os_memset(&params, 0, sizeof(params));
@@ -2822,7 +2694,8 @@ static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
return;
}
- ies = wpabuf_alloc(wpabuf_len(wps_ie) + 100);
+ ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
+ ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
if (ies == NULL) {
wpabuf_free(wps_ie);
wpas_p2p_scan_res_join(wpa_s, NULL);
@@ -2833,6 +2706,7 @@ static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
p2p_scan_ie(wpa_s->global->p2p, ies);
+ params.p2p_probe = 1;
params.extra_ies = wpabuf_head(ies);
params.extra_ies_len = wpabuf_len(ies);
@@ -2841,10 +2715,7 @@ static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
* the new scan results become available.
*/
wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- ret = ieee80211_sta_req_scan(wpa_s, &params);
- else
- ret = wpa_drv_scan(wpa_s, &params);
+ ret = wpa_drv_scan(wpa_s, &params);
wpabuf_free(ies);
@@ -2938,6 +2809,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
u8 bssid[ETH_ALEN];
int ret = 0;
enum wpa_driver_if_type iftype;
+ const u8 *if_addr;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
@@ -3033,46 +2905,34 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
- if (!wpa_s->create_p2p_iface) {
- if (auth) {
- if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
- go_intent, wpa_s->own_addr,
- force_freq, persistent_group)
- < 0)
- return -1;
- return ret;
- }
- if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
- go_intent, wpa_s->own_addr,
- force_freq, persistent_group) < 0)
+ if (wpa_s->create_p2p_iface) {
+ /* Prepare to add a new interface for the group */
+ iftype = WPA_IF_P2P_GROUP;
+ if (go_intent == 15)
+ iftype = WPA_IF_P2P_GO;
+ if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
+ wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
+ "interface for the group");
return -1;
- return ret;
- }
+ }
- /* Prepare to add a new interface for the group */
- iftype = WPA_IF_P2P_GROUP;
- if (join)
- iftype = WPA_IF_P2P_CLIENT;
- else if (go_intent == 15)
- iftype = WPA_IF_P2P_GO;
- if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
- wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
- "interface for the group");
- return -1;
- }
+ if_addr = wpa_s->pending_interface_addr;
+ } else
+ if_addr = wpa_s->own_addr;
if (auth) {
if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
- go_intent,
- wpa_s->pending_interface_addr,
+ go_intent, if_addr,
force_freq, persistent_group) < 0)
return -1;
return ret;
}
- if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method, go_intent,
- wpa_s->pending_interface_addr,
- force_freq, persistent_group) < 0) {
- wpas_p2p_remove_pending_group_interface(wpa_s);
+
+ if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
+ go_intent, if_addr, force_freq,
+ persistent_group) < 0) {
+ if (wpa_s->create_p2p_iface)
+ wpas_p2p_remove_pending_group_interface(wpa_s);
return -1;
}
return ret;
@@ -3093,9 +2953,6 @@ void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
{
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return;
- wpa_s->roc_waiting_drv_freq = 0;
- wpa_s->off_channel_freq = freq;
- wpas_send_action_cb(wpa_s, NULL);
if (wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {
p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq,
wpa_s->pending_listen_duration);
@@ -3133,7 +2990,6 @@ void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback "
"(p2p_long_listen=%d ms pending_action_tx=%p)",
wpa_s->p2p_long_listen, wpa_s->pending_action_tx);
- wpa_s->off_channel_freq = 0;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return;
if (p2p_listen_end(wpa_s->global->p2p, freq) > 0)
@@ -3186,9 +3042,9 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
}
-static void wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params,
- int freq)
+static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
+ struct p2p_go_neg_results *params,
+ int freq)
{
u8 bssid[ETH_ALEN];
int res;
@@ -3249,7 +3105,16 @@ static void wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "P2P: Force GO on the channel we are "
"already using on a shared interface");
params->freq = res;
+ } else if (res > 0 && freq != res &&
+ !(wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+ wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz "
+ "while connected on another channel (%u MHz)",
+ freq, res);
+ return -1;
}
+
+ return 0;
}
@@ -3294,11 +3159,9 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
-#ifdef ANDROID_BRCM_P2P_PATCH
/* Make sure we are not running find during connection establishment */
- wpa_printf(MSG_DEBUG, "P2P: Stopping P2P FIND, if any");
+ wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
wpas_p2p_stop_find(wpa_s);
-#endif
if (freq == 2) {
wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz "
@@ -3346,7 +3209,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
return -1;
}
- wpas_p2p_init_go_params(wpa_s, &params, freq);
+ if (wpas_p2p_init_go_params(wpa_s, &params, freq))
+ return -1;
p2p_go_params(wpa_s->global->p2p, &params);
params.persistent_group = persistent_group;
@@ -3429,7 +3293,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
if (ssid->mode != WPAS_MODE_P2P_GO)
return -1;
- wpas_p2p_init_go_params(wpa_s, &params, freq);
+ if (wpas_p2p_init_go_params(wpa_s, &params, freq))
+ return -1;
params.role_go = 1;
if (ssid->passphrase == NULL ||
@@ -3460,6 +3325,11 @@ static void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies,
struct wpa_supplicant *wpa_s = ctx;
if (wpa_s->ap_iface) {
struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
+ if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) {
+ wpabuf_free(beacon_ies);
+ wpabuf_free(proberesp_ies);
+ return;
+ }
if (beacon_ies) {
wpabuf_free(hapd->p2p_beacon_ie);
hapd->p2p_beacon_ie = beacon_ies;
@@ -3503,7 +3373,10 @@ struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
if (cfg == NULL)
return NULL;
- cfg->persistent_group = persistent_group;
+ if (persistent_group && wpa_s->conf->persistent_reconnect)
+ cfg->persistent_group = 2;
+ else if (persistent_group)
+ cfg->persistent_group = 1;
os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
if (wpa_s->max_stations &&
wpa_s->max_stations < wpa_s->conf->max_num_sta)
@@ -3533,6 +3406,9 @@ void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
return;
}
+ /* Clear any stored provisioning info */
+ p2p_clear_provisioning_info(wpa_s->global->p2p, peer_addr);
+
eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
NULL);
if (wpa_s->global->p2p)
@@ -3551,35 +3427,44 @@ void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
"provisioning not in progress");
return;
}
+
+ if (wpa_s->go_params) {
+ p2p_clear_provisioning_info(
+ wpa_s->global->p2p,
+ wpa_s->go_params->peer_interface_addr);
+ }
+
wpas_notify_p2p_wps_failed(wpa_s, fail);
}
int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- const char *config_method)
+ const char *config_method, int join)
{
u16 config_methods;
- if (os_strcmp(config_method, "display") == 0)
+ if (os_strncmp(config_method, "display", 7) == 0)
config_methods = WPS_CONFIG_DISPLAY;
- else if (os_strcmp(config_method, "keypad") == 0)
+ else if (os_strncmp(config_method, "keypad", 6) == 0)
config_methods = WPS_CONFIG_KEYPAD;
- else if (os_strcmp(config_method, "pbc") == 0 ||
- os_strcmp(config_method, "pushbutton") == 0)
+ else if (os_strncmp(config_method, "pbc", 3) == 0 ||
+ os_strncmp(config_method, "pushbutton", 10) == 0)
config_methods = WPS_CONFIG_PUSHBUTTON;
- else
+ else {
+ wpa_printf(MSG_DEBUG, "P2P: Unknown config method");
return -1;
+ }
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
return wpa_drv_p2p_prov_disc_req(wpa_s, peer_addr,
- config_methods);
+ config_methods, join);
}
if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
return -1;
return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr,
- config_methods, 0);
+ config_methods, join, 0);
}
@@ -3626,6 +3511,7 @@ void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
wpa_s->p2p_long_listen = 0;
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
+ wpa_s->p2p_cb_on_scan_complete = 0;
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
wpa_drv_p2p_stop_find(wpa_s);
@@ -3666,6 +3552,14 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
wpa_s->p2p_long_listen = 0;
+ /*
+ * Stop previous find/listen operation to avoid trying to request a new
+ * remain-on-channel operation while the driver is still running the
+ * previous one.
+ */
+ if (wpa_s->global->p2p)
+ p2p_stop_find(wpa_s->global->p2p);
+
res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
wpa_s->p2p_long_listen = timeout * 1000;
@@ -3692,9 +3586,6 @@ int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
return -1;
p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
-#ifdef ANDROID_BRCM_P2P_PATCH
- if (p2p_ie == NULL) return -1;
-#endif
ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
p2p_group, p2p_ie);
wpabuf_free(p2p_ie);
@@ -3704,6 +3595,7 @@ int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
+ const u8 *dst, const u8 *bssid,
const u8 *ie, size_t ie_len)
{
if (wpa_s->global->p2p_disabled)
@@ -3711,7 +3603,8 @@ int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
if (wpa_s->global->p2p == NULL)
return 0;
- return p2p_probe_req_rx(wpa_s->global->p2p, addr, ie, ie_len);
+ return p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
+ ie, ie_len);
}
@@ -3744,6 +3637,11 @@ void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
{
p2p_group_deinit(wpa_s->p2p_group);
wpa_s->p2p_group = NULL;
+
+ wpa_s->ap_configured_cb = NULL;
+ wpa_s->ap_configured_cb_ctx = NULL;
+ wpa_s->ap_configured_cb_data = NULL;
+ wpa_s->connect_without_scan = NULL;
}
@@ -3767,7 +3665,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
{
enum p2p_invite_role role;
u8 *bssid = NULL;
-#ifdef ANDROID_BRCM_P2P_PATCH
+#ifdef ANDROID_P2P
int go;
#endif
@@ -3779,7 +3677,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
return -1;
}
-#ifdef ANDROID_BRCM_P2P_PATCH
+#ifdef ANDROID_P2P
wpa_printf(MSG_DEBUG, "P2P: Check to see if already runnig persistent wpa_s %p grp ssid %s ssid_len %d", wpa_s, ssid->ssid, ssid->ssid_len);
if(wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go)) {
wpa_printf(MSG_DEBUG, "P2P: We are already running persistent group");
@@ -3802,7 +3700,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
bssid = wpa_s->pending_interface_addr;
} else
bssid = wpa_s->own_addr;
-#ifdef ANDROID_BRCM_P2P_PATCH
+#ifdef ANDROID_P2P
}
#endif
} else {
@@ -3853,7 +3751,7 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
role = P2P_INVITE_ROLE_ACTIVE_GO;
bssid = wpa_s->own_addr;
if (go_dev_addr == NULL)
- go_dev_addr = wpa_s->parent->own_addr;
+ go_dev_addr = wpa_s->global->p2p_dev_addr;
} else {
role = P2P_INVITE_ROLE_CLIENT;
if (wpa_s->wpa_state < WPA_ASSOCIATED) {
@@ -3889,6 +3787,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
u8 go_dev_addr[ETH_ALEN];
int network_id = -1;
int persistent;
+ int freq;
if (!wpa_s->show_group_started || !ssid)
return;
@@ -3906,28 +3805,22 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
if (wpa_s->global->p2p_group_formation == wpa_s)
wpa_s->global->p2p_group_formation = NULL;
+ freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
+ (int) wpa_s->assoc_freq;
if (ssid->passphrase == NULL && ssid->psk_set) {
char psk[65];
wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32);
wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
"%s client ssid=\"%s\" freq=%d psk=%s go_dev_addr="
MACSTR "%s",
- #ifdef ANDROID_BRCM_P2P_PATCH
- wpa_s->ifname, ssid_txt, wpa_s->current_bss->freq, psk,
- #else
- wpa_s->ifname, ssid_txt, ssid->frequency, psk,
- #endif
+ wpa_s->ifname, ssid_txt, freq, psk,
MAC2STR(go_dev_addr),
persistent ? " [PERSISTENT]" : "");
} else {
wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
"%s client ssid=\"%s\" freq=%d passphrase=\"%s\" "
"go_dev_addr=" MACSTR "%s",
- #ifdef ANDROID_BRCM_P2P_PATCH
- wpa_s->ifname, ssid_txt, wpa_s->current_bss->freq,
- #else
- wpa_s->ifname, ssid_txt, ssid->frequency,
- #endif
+ wpa_s->ifname, ssid_txt, freq,
ssid->passphrase ? ssid->passphrase : "",
MAC2STR(go_dev_addr),
persistent ? " [PERSISTENT]" : "");
@@ -3974,11 +3867,19 @@ int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
}
+static int wpas_p2p_is_client(struct wpa_supplicant *wpa_s)
+{
+ return wpa_s->current_ssid != NULL &&
+ wpa_s->current_ssid->p2p_group &&
+ wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
+}
+
+
static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
- if (wpa_s->conf->p2p_group_idle == 0) {
+ if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) {
wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - "
"disabled");
return;
@@ -3993,17 +3894,24 @@ static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s)
{
+ unsigned int timeout;
+
eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
- if (wpa_s->conf->p2p_group_idle == 0)
+ if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
return;
- if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
+ timeout = wpa_s->conf->p2p_group_idle;
+ if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
+ (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE))
+ timeout = P2P_MAX_CLIENT_IDLE;
+
+ if (timeout == 0)
return;
wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
- wpa_s->conf->p2p_group_idle);
- eloop_register_timeout(wpa_s->conf->p2p_group_idle, 0,
- wpas_p2p_group_idle_timeout, wpa_s, NULL);
+ timeout);
+ eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout,
+ wpa_s, NULL);
}
@@ -4018,23 +3926,6 @@ void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, ie_len);
}
-#ifdef ANDROID_BRCM_P2P_PATCH
-void wpas_p2p_group_remove_notif(struct wpa_supplicant *wpa_s, u16 reason_code)
-{
- if(wpa_s->global->p2p_disabled)
- return;
-
- /* If we are running a P2P Client and we received a Deauth/Disassoc from the Go, then remove
- the virutal interface on which the client is running. */
- if((wpa_s != wpa_s->parent) && (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) && (wpa_s->key_mgmt != WPA_KEY_MGMT_WPS)) {
-
- wpa_printf(MSG_DEBUG, "P2P: [EVENT_DEAUTH] Removing P2P_CLIENT virtual intf.");
- wpa_supplicant_cancel_scan(wpa_s);
- wpa_s->removal_reason = P2P_GROUP_REMOVAL_UNAVAILABLE;
- wpas_p2p_group_delete(wpa_s);
- }
-}
-#endif
void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
u16 reason_code, const u8 *ie, size_t ie_len)
@@ -4168,49 +4059,10 @@ int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
{
if (!wpa_s->ap_iface)
return -1;
-
-#ifdef ANDROID_BRCM_P2P_PATCH
-#define NOA_BUF_LEN 50
- /* Now get the NOA descriptor from the driver */
- hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
- duration);
- if(count > 0) {
- u8 noa[NOA_BUF_LEN];
- int noa_len = 0;
- wpa_printf(MSG_DEBUG, "P2P: Get NOA attribute from driver");
- noa_len = wpa_drv_get_noa(wpa_s, noa, NOA_BUF_LEN);
- if (noa_len) {
- wpa_printf(MSG_DEBUG, "P2P: Now Update NOA attributes in Beacons/ProbeRsps noa_len %d", noa_len);
- return p2p_group_notif_noa(wpa_s->p2p_group, noa, noa_len);
- }
- else
- return 0;
- }
- else
- return 0;
-#else
return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
duration);
-#endif
}
-#ifdef ANDROID_BRCM_P2P_PATCH
-int wpas_drv_set_p2p_powersave(struct wpa_supplicant *wpa_s, int legacy_ps, int opp_ps, int ctwindow)
-{
-#define NOA_BUF_LEN 50
- u8 noa[NOA_BUF_LEN];
- int noa_len = 0;
- wpa_drv_set_p2p_powersave(wpa_s, legacy_ps, opp_ps, ctwindow);
- wpa_printf(MSG_DEBUG, "P2P: Get NOA attribute from driver");
- noa_len = wpa_drv_get_noa(wpa_s, noa, NOA_BUF_LEN);
- if (noa_len) {
- wpa_printf(MSG_DEBUG, "P2P: Now Update NOA attributes in Beacons/ProbeRsps noa_len %d", noa_len);
- return p2p_group_notif_noa(wpa_s->p2p_group, noa, noa_len);
- }
- else
- return 0;
-}
-#endif
int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
{
@@ -4305,7 +4157,9 @@ void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
{
wpas_p2p_disable_cross_connect(wpa_s);
- if (!wpa_s->ap_iface)
+ if (!wpa_s->ap_iface &&
+ !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout,
+ wpa_s, NULL))
wpas_p2p_set_group_idle_timeout(wpa_s);
}
@@ -4496,3 +4350,60 @@ int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
return 0;
}
+
+
+int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
+ return 0;
+
+ return p2p_in_progress(wpa_s->global->p2p);
+}
+
+
+void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid)
+
+{
+ if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
+ eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
+ wpa_s->parent, NULL) > 0) {
+ wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
+ "P2P group network getting removed");
+ wpas_p2p_group_formation_timeout(wpa_s->parent, NULL);
+ }
+}
+
+
+struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
+ const u8 *addr)
+{
+ struct wpa_ssid *s;
+ size_t i;
+
+ for (s = wpa_s->conf->ssid; s; s = s->next) {
+ if (s->disabled != 2)
+ continue;
+ if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
+ return s; /* peer is GO in the persistent group */
+ if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
+ continue;
+ for (i = 0; i < s->num_p2p_clients; i++) {
+ if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
+ addr, ETH_ALEN) == 0)
+ return s; /* peer is P2P client in persistent
+ * group */
+ }
+ }
+
+ return NULL;
+}
+
+
+void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *addr)
+{
+ if (addr == NULL)
+ return;
+ wpas_p2p_add_persistent_group_client(wpa_s, addr);
+}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 5be9ba2..6fe1e1d 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -31,6 +31,10 @@ void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq, unsigned int duration);
void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq);
+#ifdef ANDROID_P2P
+void wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
+ int freq);
+#endif
int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
int freq);
@@ -43,7 +47,7 @@ struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int registrar);
int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- const char *config_method);
+ const char *config_method, int join);
void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
const u8 *data, size_t data_len,
enum p2p_send_action_result result);
@@ -58,6 +62,7 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
u8 *buf, size_t len, int p2p_group);
int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
+ const u8 *dst, const u8 *bssid,
const u8 *ie, size_t ie_len);
void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
const u8 *sa, const u8 *bssid,
@@ -72,17 +77,18 @@ void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id);
void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
const u8 *dev_addr, const u8 *pri_dev_type,
const char *dev_name, u16 supp_config_methods,
- u8 dev_capab, u8 group_capab);
+ u8 dev_capab, u8 group_capab, const u8 *group_id,
+ size_t group_id_len);
void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods);
void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
u16 update_indic, const u8 *tlvs, size_t tlvs_len);
void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
const u8 *tlvs, size_t tlvs_len);
-void * wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *tlvs);
-void * wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
- u8 version, const char *query);
-int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, void *req);
+u64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
+ const struct wpabuf *tlvs);
+u64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
+ u8 version, const char *query);
+int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req);
void wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq,
const u8 *dst, u8 dialog_token,
const struct wpabuf *resp_tlvs);
@@ -108,12 +114,6 @@ int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
unsigned int interval);
void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
u16 reason_code, const u8 *ie, size_t ie_len);
-#ifdef ANDROID_BRCM_P2P_PATCH
-void wpas_p2p_group_remove_notif(struct wpa_supplicant *wpa_s,
- u16 reason_code);
-int wpas_drv_set_p2p_powersave(struct wpa_supplicant *wpa_s, int legacy_ps,
- int opp_ps, int ctwindow);
-#endif /* ANDROID_BRCM_P2P_PATCH */
void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
u16 reason_code, const u8 *ie, size_t ie_len);
void wpas_p2p_update_config(struct wpa_supplicant *wpa_s);
@@ -132,5 +132,12 @@ int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr);
int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s);
void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail);
+int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s);
+void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid);
+struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
+ const u8 *addr);
+void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *addr);
#endif /* P2P_SUPPLICANT_H */
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index bb64e9a..e453cfc 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -20,7 +20,6 @@
#include "config.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
-#include "mlme.h"
#include "wps_supplicant.h"
#include "p2p_supplicant.h"
#include "p2p/p2p.h"
@@ -52,13 +51,13 @@ static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_WPS
-static int wpas_wps_in_use(struct wpa_config *conf,
+static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
enum wps_request_type *req_type)
{
struct wpa_ssid *ssid;
int wps = 0;
- for (ssid = conf->ssid; ssid; ssid = ssid->next) {
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
continue;
@@ -71,6 +70,14 @@ static int wpas_wps_in_use(struct wpa_config *conf,
return 2;
}
+#ifdef CONFIG_P2P
+ wpa_s->wps->dev.p2p = 1;
+ if (!wps) {
+ wps = 1;
+ *req_type = WPS_REQ_ENROLLEE_INFO;
+ }
+#endif /* CONFIG_P2P */
+
return wps;
}
#endif /* CONFIG_WPS */
@@ -192,16 +199,71 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
wpa_supplicant_notify_scanning(wpa_s, 1);
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- ret = ieee80211_sta_req_scan(wpa_s, params);
- else
- ret = wpa_drv_scan(wpa_s, params);
-
+ ret = wpa_drv_scan(wpa_s, params);
if (ret) {
wpa_supplicant_notify_scanning(wpa_s, 0);
wpas_notify_scan_done(wpa_s, 0);
- } else
+ } else {
wpa_s->scan_runs++;
+ wpa_s->normal_scans++;
+ }
+
+ return ret;
+}
+
+
+static void
+wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+
+ wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan");
+
+ if (wpa_supplicant_req_sched_scan(wpa_s))
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+}
+
+
+static void
+wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+
+ wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
+
+ wpa_s->sched_scan_timed_out = 1;
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+}
+
+
+static int
+wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
+ struct wpa_driver_scan_params *params,
+ int interval)
+{
+ int ret;
+
+ wpa_supplicant_notify_scanning(wpa_s, 1);
+ ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000);
+ if (ret)
+ wpa_supplicant_notify_scanning(wpa_s, 0);
+ else
+ wpa_s->sched_scanning = 1;
+
+ return ret;
+}
+
+
+static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
+{
+ int ret;
+
+ ret = wpa_drv_stop_sched_scan(wpa_s);
+ if (ret) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
+ /* TODO: what to do if stopping fails? */
+ return -1;
+ }
return ret;
}
@@ -240,16 +302,128 @@ wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
}
-static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
+static void wpa_supplicant_optimize_freqs(
+ struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_ssid *ssid;
- int scan_req = 0, ret;
- struct wpabuf *wps_ie = NULL;
+#ifdef CONFIG_P2P
+ if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
+ wpa_s->go_params) {
+ /* Optimize provisioning state scan based on GO information */
+ if (wpa_s->p2p_in_provisioning < 5 &&
+ wpa_s->go_params->freq > 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
+ "preferred frequency %d MHz",
+ wpa_s->go_params->freq);
+ params->freqs = os_zalloc(2 * sizeof(int));
+ if (params->freqs)
+ params->freqs[0] = wpa_s->go_params->freq;
+ } else if (wpa_s->p2p_in_provisioning < 8 &&
+ wpa_s->go_params->freq_list[0]) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
+ "channels");
+ int_array_concat(&params->freqs,
+ wpa_s->go_params->freq_list);
+ if (params->freqs)
+ int_array_sort_unique(params->freqs);
+ }
+ wpa_s->p2p_in_provisioning++;
+ }
+#endif /* CONFIG_P2P */
+
+#ifdef CONFIG_WPS
+ if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
+ /*
+ * Optimize post-provisioning scan based on channel used
+ * during provisioning.
+ */
+ wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
+ "that was used during provisioning", wpa_s->wps_freq);
+ params->freqs = os_zalloc(2 * sizeof(int));
+ if (params->freqs)
+ params->freqs[0] = wpa_s->wps_freq;
+ wpa_s->after_wps--;
+ }
+
+#endif /* CONFIG_WPS */
+}
+
+
+#ifdef CONFIG_INTERWORKING
+static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
+ struct wpabuf *buf)
+{
+ if (wpa_s->conf->interworking == 0)
+ return;
+
+ wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB);
+ wpabuf_put_u8(buf, 4);
+ wpabuf_put_u8(buf, 0x00);
+ wpabuf_put_u8(buf, 0x00);
+ wpabuf_put_u8(buf, 0x00);
+ wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */
+
+ wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
+ wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
+ 1 + ETH_ALEN);
+ wpabuf_put_u8(buf, wpa_s->conf->access_network_type);
+ /* No Venue Info */
+ if (!is_zero_ether_addr(wpa_s->conf->hessid))
+ wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN);
+}
+#endif /* CONFIG_INTERWORKING */
+
+
+static struct wpabuf *
+wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s,
+ struct wpa_driver_scan_params *params)
+{
+ struct wpabuf *extra_ie = NULL;
#ifdef CONFIG_WPS
int wps = 0;
enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
#endif /* CONFIG_WPS */
+
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->interworking &&
+ wpabuf_resize(&extra_ie, 100) == 0)
+ wpas_add_interworking_elements(wpa_s, extra_ie);
+#endif /* CONFIG_INTERWORKING */
+
+#ifdef CONFIG_WPS
+ wps = wpas_wps_in_use(wpa_s, &req_type);
+
+ if (wps) {
+ struct wpabuf *wps_ie;
+ wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev,
+ wpa_s->wps->uuid, req_type,
+ 0, NULL);
+ if (wps_ie) {
+ if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
+ wpabuf_put_buf(extra_ie, wps_ie);
+ wpabuf_free(wps_ie);
+ }
+ }
+
+#ifdef CONFIG_P2P
+ if (wps) {
+ size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
+ if (wpabuf_resize(&extra_ie, ielen) == 0)
+ wpas_p2p_scan_ie(wpa_s, extra_ie);
+ }
+#endif /* CONFIG_P2P */
+
+#endif /* CONFIG_WPS */
+
+ return extra_ie;
+}
+
+
+static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct wpa_ssid *ssid;
+ int scan_req = 0, ret;
+ struct wpabuf *extra_ie;
struct wpa_driver_scan_params params;
size_t max_ssids;
enum wpa_states prev_state;
@@ -284,8 +458,21 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
return;
}
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ||
- wpa_s->conf->ap_scan == 2)
+#ifdef CONFIG_P2P
+ if (wpas_p2p_in_progress(wpa_s)) {
+ if (wpa_s->wpa_state == WPA_SCANNING) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan "
+ "while P2P operation is in progress");
+ wpa_supplicant_req_scan(wpa_s, 5, 0);
+ } else {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Do not request scan while "
+ "P2P operation is in progress");
+ }
+ return;
+ }
+#endif /* CONFIG_P2P */
+
+ if (wpa_s->conf->ap_scan == 2)
max_ssids = 1;
else {
max_ssids = wpa_s->max_scan_ssids;
@@ -293,10 +480,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
max_ssids = WPAS_MAX_SCAN_SSIDS;
}
-#ifdef CONFIG_WPS
- wps = wpas_wps_in_use(wpa_s->conf, &req_type);
-#endif /* CONFIG_WPS */
-
scan_req = wpa_s->scan_req;
wpa_s->scan_req = 0;
@@ -401,71 +584,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
"SSID");
}
-#ifdef CONFIG_P2P
- wpa_s->wps->dev.p2p = 1;
- if (!wps) {
- wps = 1;
- req_type = WPS_REQ_ENROLLEE_INFO;
- }
-
- if (params.freqs == NULL && wpa_s->p2p_in_provisioning &&
- wpa_s->go_params) {
- /* Optimize provisioning state scan based on GO information */
- if (wpa_s->p2p_in_provisioning < 5 &&
- wpa_s->go_params->freq > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
- "preferred frequency %d MHz",
- wpa_s->go_params->freq);
- params.freqs = os_zalloc(2 * sizeof(int));
- if (params.freqs)
- params.freqs[0] = wpa_s->go_params->freq;
- } else if (wpa_s->p2p_in_provisioning < 8 &&
- wpa_s->go_params->freq_list[0]) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
- "channels");
- int_array_concat(&params.freqs,
- wpa_s->go_params->freq_list);
- if (params.freqs)
- int_array_sort_unique(params.freqs);
- }
- wpa_s->p2p_in_provisioning++;
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_WPS
- if (params.freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
- /*
- * Optimize post-provisioning scan based on channel used
- * during provisioning.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
- "that was used during provisioning", wpa_s->wps_freq);
- params.freqs = os_zalloc(2 * sizeof(int));
- if (params.freqs)
- params.freqs[0] = wpa_s->wps_freq;
- wpa_s->after_wps--;
- }
-
- if (wps) {
- wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev,
- wpa_s->wps->uuid, req_type,
- 0, NULL);
- if (wps_ie) {
- params.extra_ies = wpabuf_head(wps_ie);
- params.extra_ies_len = wpabuf_len(wps_ie);
- }
- }
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_P2P
- if (wps_ie) {
- if (wpabuf_resize(&wps_ie, 100) == 0) {
- wpas_p2p_scan_ie(wpa_s, wps_ie);
- params.extra_ies = wpabuf_head(wps_ie);
- params.extra_ies_len = wpabuf_len(wps_ie);
- }
- }
-#endif /* CONFIG_P2P */
+ wpa_supplicant_optimize_freqs(wpa_s, &params);
+ extra_ie = wpa_supplicant_extra_ies(wpa_s, &params);
if (params.freqs == NULL && wpa_s->next_scan_freqs) {
wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
@@ -477,10 +597,24 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
params.filter_ssids = wpa_supplicant_build_filter_ssids(
wpa_s->conf, &params.num_filter_ssids);
+ if (extra_ie) {
+ params.extra_ies = wpabuf_head(extra_ie);
+ params.extra_ies_len = wpabuf_len(extra_ie);
+ }
+
+#ifdef CONFIG_P2P
+ if (wpa_s->p2p_in_provisioning) {
+ /*
+ * The interface may not yet be in P2P mode, so we have to
+ * explicitly request P2P probe to disable CCK rates.
+ */
+ params.p2p_probe = 1;
+ }
+#endif /* CONFIG_P2P */
ret = wpa_supplicant_trigger_scan(wpa_s, &params);
- wpabuf_free(wps_ie);
+ wpabuf_free(extra_ie);
os_free(params.freqs);
os_free(params.filter_ssids);
@@ -535,6 +669,215 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
/**
+ * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @sec: Number of seconds after which to scan
+ * @usec: Number of microseconds after which to scan
+ *
+ * This function is used to schedule periodic scans for neighboring
+ * access points after the specified time.
+ */
+int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
+ int sec, int usec)
+{
+ if (!wpa_s->sched_scan_supported)
+ return -1;
+
+ eloop_register_timeout(sec, usec,
+ wpa_supplicant_delayed_sched_scan_timeout,
+ wpa_s, NULL);
+
+ return 0;
+}
+
+
+/**
+ * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
+ * @wpa_s: Pointer to wpa_supplicant data
+ *
+ * This function is used to schedule periodic scans for neighboring
+ * access points repeating the scan continuously.
+ */
+int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_driver_scan_params params;
+ enum wpa_states prev_state;
+ struct wpa_ssid *ssid;
+ struct wpabuf *wps_ie = NULL;
+ int ret;
+ unsigned int max_sched_scan_ssids;
+ int wildcard = 0;
+ int need_ssids;
+
+ if (!wpa_s->sched_scan_supported)
+ return -1;
+
+ if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
+ max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
+ else
+ max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
+ if (max_sched_scan_ssids < 1)
+ return -1;
+
+ if (wpa_s->sched_scanning) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning");
+ return 0;
+ }
+
+ need_ssids = 0;
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+ if (!ssid->disabled && !ssid->scan_ssid) {
+ /* Use wildcard SSID to find this network */
+ wildcard = 1;
+ } else if (!ssid->disabled && ssid->ssid_len)
+ need_ssids++;
+ }
+ if (wildcard)
+ need_ssids++;
+
+ if (wpa_s->normal_scans < 3 &&
+ (need_ssids <= wpa_s->max_scan_ssids ||
+ wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
+ /*
+ * When normal scan can speed up operations, use that for the
+ * first operations before starting the sched_scan to allow
+ * user space sleep more. We do this only if the normal scan
+ * has functionality that is suitable for this or if the
+ * sched_scan does not have better support for multiple SSIDs.
+ */
+ wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
+ "sched_scan for initial scans (normal_scans=%d)",
+ wpa_s->normal_scans);
+ return -1;
+ }
+
+ os_memset(&params, 0, sizeof(params));
+
+ /* If we can't allocate space for the filters, we just don't filter */
+ params.filter_ssids = os_zalloc(wpa_s->max_match_sets *
+ sizeof(struct wpa_driver_scan_filter));
+
+ prev_state = wpa_s->wpa_state;
+ if (wpa_s->wpa_state == WPA_DISCONNECTED ||
+ wpa_s->wpa_state == WPA_INACTIVE)
+ wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
+
+ /* Find the starting point from which to continue scanning */
+ ssid = wpa_s->conf->ssid;
+ if (wpa_s->prev_sched_ssid) {
+ while (ssid) {
+ if (ssid == wpa_s->prev_sched_ssid) {
+ ssid = ssid->next;
+ break;
+ }
+ ssid = ssid->next;
+ }
+ }
+
+ if (!ssid || !wpa_s->prev_sched_ssid) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
+
+ wpa_s->sched_scan_interval = 10;
+ wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
+ wpa_s->first_sched_scan = 1;
+ ssid = wpa_s->conf->ssid;
+ wpa_s->prev_sched_ssid = ssid;
+ }
+
+ if (wildcard) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan");
+ params.num_ssids++;
+ }
+
+ while (ssid) {
+ if (ssid->disabled)
+ goto next;
+
+ if (params.num_filter_ssids < wpa_s->max_match_sets &&
+ params.filter_ssids && ssid->ssid && ssid->ssid_len) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s",
+ wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+ os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid,
+ ssid->ssid, ssid->ssid_len);
+ params.filter_ssids[params.num_filter_ssids].ssid_len =
+ ssid->ssid_len;
+ params.num_filter_ssids++;
+ } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len)
+ {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID "
+ "filter for sched_scan - drop filter");
+ os_free(params.filter_ssids);
+ params.filter_ssids = NULL;
+ params.num_filter_ssids = 0;
+ }
+
+ if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) {
+ if (params.num_ssids == max_sched_scan_ssids)
+ break; /* only room for broadcast SSID */
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "add to active scan ssid: %s",
+ wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+ params.ssids[params.num_ssids].ssid =
+ ssid->ssid;
+ params.ssids[params.num_ssids].ssid_len =
+ ssid->ssid_len;
+ params.num_ssids++;
+ if (params.num_ssids >= max_sched_scan_ssids) {
+ wpa_s->prev_sched_ssid = ssid;
+ break;
+ }
+ }
+
+ next:
+ wpa_s->prev_sched_ssid = ssid;
+ ssid = ssid->next;
+ }
+
+ if (params.num_filter_ssids == 0) {
+ os_free(params.filter_ssids);
+ params.filter_ssids = NULL;
+ }
+
+ if (wpa_s->wps)
+ wps_ie = wpa_supplicant_extra_ies(wpa_s, &params);
+
+ if (ssid || !wpa_s->first_sched_scan) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Starting sched scan: interval %d (no timeout)",
+ wpa_s->sched_scan_interval);
+ } else {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Starting sched scan: interval %d timeout %d",
+ wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout);
+ }
+
+ ret = wpa_supplicant_start_sched_scan(wpa_s, &params,
+ wpa_s->sched_scan_interval);
+ wpabuf_free(wps_ie);
+ os_free(params.filter_ssids);
+ if (ret) {
+ wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
+ if (prev_state != wpa_s->wpa_state)
+ wpa_supplicant_set_state(wpa_s, prev_state);
+ return ret;
+ }
+
+ /* If we have more SSIDs to scan, add a timeout so we scan them too */
+ if (ssid || !wpa_s->first_sched_scan) {
+ wpa_s->sched_scan_timed_out = 0;
+ eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
+ wpa_supplicant_sched_scan_timeout,
+ wpa_s, NULL);
+ wpa_s->first_sched_scan = 0;
+ wpa_s->sched_scan_timeout /= 2;
+ wpa_s->sched_scan_interval *= 2;
+ }
+
+ return 0;
+}
+
+
+/**
* wpa_supplicant_cancel_scan - Cancel a scheduled scan request
* @wpa_s: Pointer to wpa_supplicant data
*
@@ -549,6 +892,23 @@ void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
}
+/**
+ * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
+ * @wpa_s: Pointer to wpa_supplicant data
+ *
+ * This function is used to stop a periodic scheduled scan.
+ */
+void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s->sched_scanning)
+ return;
+
+ wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
+ eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
+ wpa_supplicant_stop_sched_scan(wpa_s);
+}
+
+
void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
int scanning)
{
@@ -686,15 +1046,28 @@ struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
}
+/*
+ * Channels with a great SNR can operate at full rate. What is a great SNR?
+ * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general
+ * rule of thumb is that any SNR above 20 is good." This one
+ * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23
+ * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a
+ * conservative value.
+ */
+#define GREAT_SNR 30
+
/* Compare function for sorting scan results. Return >0 if @b is considered
* better. */
static int wpa_scan_result_compar(const void *a, const void *b)
{
+#define IS_5GHZ(n) (n > 4000)
+#define MIN(a,b) a < b ? a : b
struct wpa_scan_res **_wa = (void *) a;
struct wpa_scan_res **_wb = (void *) b;
struct wpa_scan_res *wa = *_wa;
struct wpa_scan_res *wb = *_wb;
int wpa_a, wpa_b, maxrate_a, maxrate_b;
+ int snr_a, snr_b;
/* WPA/WPA2 support preferred */
wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
@@ -715,23 +1088,37 @@ static int wpa_scan_result_compar(const void *a, const void *b)
(wb->caps & IEEE80211_CAP_PRIVACY) == 0)
return -1;
- /* best/max rate preferred if signal level close enough XXX */
- if ((wa->level && wb->level && abs(wb->level - wa->level) < 5) ||
+ if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) &&
+ !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) {
+ snr_a = MIN(wa->level - wa->noise, GREAT_SNR);
+ snr_b = MIN(wb->level - wb->noise, GREAT_SNR);
+ } else {
+ /* Not suitable information to calculate SNR, so use level */
+ snr_a = wa->level;
+ snr_b = wb->level;
+ }
+
+ /* best/max rate preferred if SNR close enough */
+ if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
(wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
maxrate_a = wpa_scan_get_max_rate(wa);
maxrate_b = wpa_scan_get_max_rate(wb);
if (maxrate_a != maxrate_b)
return maxrate_b - maxrate_a;
+ if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
+ return IS_5GHZ(wa->freq) ? -1 : 1;
}
/* use freq for channel preference */
- /* all things being equal, use signal level; if signal levels are
+ /* all things being equal, use SNR; if SNRs are
* identical, use quality values since some drivers may only report
* that value and leave the signal level zero */
- if (wb->level == wa->level)
+ if (snr_b == snr_a)
return wb->qual - wa->qual;
- return wb->level - wa->level;
+ return snr_b - snr_a;
+#undef MIN
+#undef IS_5GHZ
}
@@ -783,6 +1170,37 @@ static int wpa_scan_result_wps_compar(const void *a, const void *b)
#endif /* CONFIG_WPS */
+static void dump_scan_res(struct wpa_scan_results *scan_res)
+{
+#ifndef CONFIG_NO_STDOUT_DEBUG
+ size_t i;
+
+ if (scan_res->res == NULL || scan_res->num == 0)
+ return;
+
+ wpa_printf(MSG_EXCESSIVE, "Sorted scan results");
+
+ for (i = 0; i < scan_res->num; i++) {
+ struct wpa_scan_res *r = scan_res->res[i];
+ if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID))
+ == WPA_SCAN_LEVEL_DBM) {
+ int snr = r->level - r->noise;
+ wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
+ "noise=%d level=%d snr=%d%s flags=0x%x",
+ MAC2STR(r->bssid), r->freq, r->qual,
+ r->noise, r->level, snr,
+ snr >= GREAT_SNR ? "*" : "", r->flags);
+ } else {
+ wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
+ "noise=%d level=%d flags=0x%x",
+ MAC2STR(r->bssid), r->freq, r->qual,
+ r->noise, r->level, r->flags);
+ }
+ }
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+}
+
+
/**
* wpa_supplicant_get_scan_results - Get scan results
* @wpa_s: Pointer to wpa_supplicant data
@@ -802,10 +1220,7 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
size_t i;
int (*compar)(const void *, const void *) = wpa_scan_result_compar;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- scan_res = ieee80211_sta_get_scan_results(wpa_s);
- else
- scan_res = wpa_drv_get_scan_results2(wpa_s);
+ scan_res = wpa_drv_get_scan_results2(wpa_s);
if (scan_res == NULL) {
wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
return NULL;
@@ -821,6 +1236,7 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *),
compar);
+ dump_scan_res(scan_res);
wpa_bss_update_start(wpa_s);
for (i = 0; i < scan_res->num; i++)
@@ -841,17 +1257,3 @@ int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
return 0;
}
-
-
-void wpa_scan_results_free(struct wpa_scan_results *res)
-{
- size_t i;
-
- if (res == NULL)
- return;
-
- for (i = 0; i < res->num; i++)
- os_free(res->res[i]);
- os_free(res->res);
- os_free(res);
-}
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 025b815..7fb84e6 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -17,7 +17,11 @@
int wpa_supplicant_enabled_networks(struct wpa_config *conf);
void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
+int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
+ int sec, int usec);
+int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s);
void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
+void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s);
void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
int scanning);
struct wpa_driver_scan_params;
@@ -34,6 +38,5 @@ struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
u32 vendor_type);
struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
const struct wpa_scan_res *res, u32 vendor_type);
-void wpa_scan_results_free(struct wpa_scan_results *res);
#endif /* SCAN_H */
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 325ffc5..c5e47d1 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -29,7 +29,6 @@
#include "wps_supplicant.h"
#include "p2p_supplicant.h"
#include "notify.h"
-#include "blacklist.h"
#include "bss.h"
#include "scan.h"
#include "sme.h"
@@ -72,6 +71,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
params.bssid = bss->bssid;
params.ssid = bss->ssid;
params.ssid_len = bss->ssid_len;
+ params.p2p = ssid->p2p_group;
if (wpa_s->sme.ssid_len != params.ssid_len ||
os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0)
@@ -115,11 +115,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
- (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
- WPA_KEY_MGMT_FT_IEEE8021X |
- WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_IEEE8021X_SHA256 |
- WPA_KEY_MGMT_PSK_SHA256))) {
+ wpa_key_mgmt_wpa(ssid->key_mgmt)) {
int try_opportunistic;
try_opportunistic = ssid->proactive_key_caching &&
(ssid->proto & WPA_PROTO_RSN);
@@ -135,11 +131,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
"key management and encryption suites");
return;
}
- } else if (ssid->key_mgmt &
- (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
- WPA_KEY_MGMT_WPA_NONE | WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_PSK_SHA256 |
- WPA_KEY_MGMT_IEEE8021X_SHA256)) {
+ } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
wpa_s->sme.assoc_req_ie,
@@ -178,8 +170,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
}
- if (md && ssid->key_mgmt & (WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_FT_IEEE8021X)) {
+ if (md && wpa_key_mgmt_ft(ssid->key_mgmt)) {
if (wpa_s->sme.assoc_req_ie_len + 5 <
sizeof(wpa_s->sme.assoc_req_ie)) {
struct rsn_mdie *mdie;
@@ -226,17 +217,35 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
u8 *pos;
size_t len;
int res;
- int p2p_group;
- p2p_group = wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE;
pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
len = sizeof(wpa_s->sme.assoc_req_ie) -
wpa_s->sme.assoc_req_ie_len;
- res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, p2p_group);
+ res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
+ ssid->p2p_group);
if (res >= 0)
wpa_s->sme.assoc_req_ie_len += res;
}
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->interworking) {
+ u8 *pos = wpa_s->sme.assoc_req_ie;
+ if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN)
+ pos += 2 + pos[1];
+ os_memmove(pos + 6, pos,
+ wpa_s->sme.assoc_req_ie_len -
+ (pos - wpa_s->sme.assoc_req_ie));
+ wpa_s->sme.assoc_req_ie_len += 6;
+ *pos++ = WLAN_EID_EXT_CAPAB;
+ *pos++ = 4;
+ *pos++ = 0x00;
+ *pos++ = 0x00;
+ *pos++ = 0x00;
+ *pos++ = 0x80; /* Bit 31 - Interworking */
+ }
+#endif /* CONFIG_INTERWORKING */
+
+ wpa_supplicant_cancel_sched_scan(wpa_s);
wpa_supplicant_cancel_scan(wpa_s);
wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR
@@ -256,7 +265,8 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
if (wpa_drv_authenticate(wpa_s, &params) < 0) {
wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
"driver failed");
- wpa_supplicant_req_scan(wpa_s, 1, 0);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ wpas_connection_failed(wpa_s, bss->bssid);
return;
}
@@ -392,16 +402,17 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
os_memset(&elems, 0, sizeof(elems));
}
- if (elems.rsn_ie)
+ if (elems.rsn_ie) {
+ params.wpa_proto = WPA_PROTO_RSN;
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
elems.rsn_ie_len + 2);
- else if (elems.wpa_ie)
+ } else if (elems.wpa_ie) {
+ params.wpa_proto = WPA_PROTO_WPA;
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
elems.wpa_ie_len + 2);
- else
+ } else
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
- if (elems.p2p &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
+ if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
params.p2p = 1;
if (wpa_s->parent->set_sta_uapsd)
@@ -492,6 +503,7 @@ void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
}
@@ -509,8 +521,7 @@ void sme_event_disassoc(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received");
- if (wpa_s->sme.prev_bssid_set &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)) {
+ if (wpa_s->sme.prev_bssid_set) {
/*
* cfg80211/mac80211 can get into somewhat confused state if
* the AP only disassociates us and leaves us in authenticated
@@ -628,7 +639,7 @@ static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s,
os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN);
if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
wpa_s->own_addr, wpa_s->bssid,
- req, sizeof(req)) < 0)
+ req, sizeof(req), 0) < 0)
wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query "
"Request");
}
@@ -677,7 +688,7 @@ static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
}
-void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
+static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
{
eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
os_free(wpa_s->sme.sa_query_trans_id);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index f09a6f0..a110171 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -24,6 +24,7 @@
#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/edit.h"
+#include "utils/list.h"
#include "common/version.h"
#ifdef ANDROID
#include <cutils/properties.h>
@@ -103,6 +104,15 @@ static const char *action_file = NULL;
static int ping_interval = 5;
static int interactive = 0;
+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 */
+
static void print_help(void);
static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
@@ -126,6 +136,164 @@ static void usage(void)
}
+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)
+{
+ const char *end;
+ char *buf;
+ end = os_strchr(txt, ' ');
+ if (end == NULL)
+ end = txt + os_strlen(txt);
+ buf = os_malloc(end - txt + 1);
+ if (buf == NULL)
+ return;
+ os_memcpy(buf, txt, end - txt);
+ buf[end - txt] = '\0';
+ 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);
+}
+
+
+static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
+{
+ const char *end;
+ char *buf;
+ int ret;
+ end = os_strchr(txt, ' ');
+ if (end == NULL)
+ end = txt + os_strlen(txt);
+ buf = os_malloc(end - txt + 1);
+ if (buf == NULL)
+ return -1;
+ os_memcpy(buf, txt, end - txt);
+ buf[end - txt] = '\0';
+ ret = cli_txt_list_add(txt_list, buf);
+ os_free(buf);
+ return ret;
+}
+#endif /* CONFIG_P2P */
+
+
+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_zalloc((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;
@@ -286,8 +454,11 @@ static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
- int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
- return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
+ if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
+ return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
+ if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
+ return wpa_ctrl_command(ctrl, "STATUS-WPS");
+ return wpa_ctrl_command(ctrl, "STATUS");
}
@@ -381,13 +552,17 @@ static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
return 0;
}
- if (argc != 2) {
+ if (argc != 1 && argc != 2) {
printf("Invalid SET command: needs two arguments (variable "
"name and value)\n");
return -1;
}
- res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
+ if (argc == 1)
+ res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
+ else
+ res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
+ argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET command.\n");
return -1;
@@ -1499,6 +1674,21 @@ static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
+static char ** wpa_cli_complete_bss(const char *str, int pos)
+{
+ int arg = get_cmd_arg_num(str, pos);
+ char **res = NULL;
+
+ switch (arg) {
+ case 1:
+ res = cli_txt_list_array(&bsses);
+ break;
+ }
+
+ return res;
+}
+
+
static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -1792,6 +1982,21 @@ static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
}
+static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
+{
+ int arg = get_cmd_arg_num(str, pos);
+ char **res = NULL;
+
+ switch (arg) {
+ case 1:
+ res = cli_txt_list_array(&p2p_peers);
+ break;
+ }
+
+ return res;
+}
+
+
static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -1829,6 +2034,21 @@ static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
}
+static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
+{
+ int arg = get_cmd_arg_num(str, pos);
+ char **res = NULL;
+
+ switch (arg) {
+ case 1:
+ res = cli_txt_list_array(&p2p_groups);
+ break;
+ }
+
+ return res;
+}
+
+
static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -1857,15 +2077,19 @@ static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
char cmd[128];
int res;
- if (argc != 2) {
- printf("Invalid P2P_PROV_DISC command: needs two arguments "
- "(address and config method\n"
- "(display, keypad, or pbc)\n");
+ if (argc != 2 && argc != 3) {
+ printf("Invalid P2P_PROV_DISC command: needs at least "
+ "two arguments, address and config method\n"
+ "(display, keypad, or pbc) and an optional join\n");
return -1;
}
- res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
- argv[0], argv[1]);
+ if (argc == 3)
+ res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
+ argv[0], argv[1], argv[2]);
+ else
+ res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
+ argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd))
return -1;
cmd[sizeof(cmd) - 1] = '\0';
@@ -2099,6 +2323,21 @@ static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
}
+static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
+{
+ int arg = get_cmd_arg_num(str, pos);
+ char **res = NULL;
+
+ switch (arg) {
+ case 1:
+ res = cli_txt_list_array(&p2p_peers);
+ break;
+ }
+
+ return res;
+}
+
+
static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
char *addr, size_t addr_len,
int discovered)
@@ -2144,13 +2383,13 @@ static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
addr, sizeof(addr), discovered))
- return 0;
+ return -1;
do {
os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
} while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
discovered) == 0);
- return -1;
+ return 0;
}
@@ -2267,6 +2506,80 @@ static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "FETCH_ANQP");
+}
+
+
+static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
+}
+
+
+static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char cmd[100];
+ int res;
+
+ if (argc == 0)
+ return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
+
+ res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd))
+ return -1;
+ cmd[sizeof(cmd) - 1] = '\0';
+ return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char cmd[100];
+ int res;
+
+ if (argc != 1) {
+ printf("Invalid INTERWORKING_CONNECT commands: needs one "
+ "argument (BSSID)\n");
+ return -1;
+ }
+
+ res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
+ argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd))
+ return -1;
+ cmd[sizeof(cmd) - 1] = '\0';
+ return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+ char cmd[100];
+ int res;
+
+ if (argc != 2) {
+ printf("Invalid ANQP_GET command: needs two arguments "
+ "(addr and info id list)\n");
+ return -1;
+ }
+
+ res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
+ argv[0], argv[1]);
+ if (res < 0 || (size_t) res >= sizeof(cmd))
+ return -1;
+ cmd[sizeof(cmd) - 1] = '\0';
+ return wpa_ctrl_command(ctrl, cmd);
+}
+#endif /* CONFIG_INTERWORKING */
+
+
static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -2357,6 +2670,13 @@ static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
}
+static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
+}
+
+
static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
char cmd[256];
@@ -2472,7 +2792,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
"blacklist = display the blacklist" },
{ "log_level", wpa_cli_cmd_log_level,
cli_cmd_flag_none,
- "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n"
+ "<level> [<timestamp>] = update the log level/timestamp\n"
"log_level = display the current log level and log options" },
{ "list_networks", wpa_cli_cmd_list_networks,
cli_cmd_flag_none,
@@ -2690,6 +3010,21 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
"[<period> <interval>] = set extended listen timing" },
#endif /* CONFIG_P2P */
+
+#ifdef CONFIG_INTERWORKING
+ { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
+ "= fetch ANQP information for all APs" },
+ { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
+ "= stop fetch_anqp operation" },
+ { "interworking_select", wpa_cli_cmd_interworking_select,
+ cli_cmd_flag_none,
+ "[auto] = perform Interworking network selection" },
+ { "interworking_connect", wpa_cli_cmd_interworking_connect,
+ cli_cmd_flag_none,
+ "<BSSID> = connect using Interworking credentials" },
+ { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
+ "<addr> <info id>[,<info id>]... = request ANQP information" },
+#endif /* CONFIG_INTERWORKING */
{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
"<0/1> = disable/enable automatic reconnection" },
{ "tdls_discover", wpa_cli_cmd_tdls_discover,
@@ -2704,6 +3039,8 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "signal_poll", wpa_cli_cmd_signal_poll,
cli_cmd_flag_none,
"= get signal parameters" },
+ { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
+ "= trigger IEEE 802.1X/EAPOL reauthentication" },
{ "driver", wpa_cli_cmd_driver,
cli_cmd_flag_none,
"<command> = driver private commands" },
@@ -2784,6 +3121,17 @@ static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
{
int i;
+ if (os_strcasecmp(cmd, "bss") == 0)
+ return wpa_cli_complete_bss(str, pos);
+#ifdef CONFIG_P2P
+ if (os_strcasecmp(cmd, "p2p_connect") == 0)
+ return wpa_cli_complete_p2p_connect(str, pos);
+ if (os_strcasecmp(cmd, "p2p_peer") == 0)
+ return wpa_cli_complete_p2p_peer(str, pos);
+ if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
+ return wpa_cli_complete_p2p_group_remove(str, pos);
+#endif /* CONFIG_P2P */
+
for (i = 0; wpa_cli_commands[i].cmd; i++) {
if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
edit_clear_line();
@@ -2961,19 +3309,20 @@ static void wpa_cli_action_process(const char *msg)
wpa_cli_exec(action_file, ctrl_ifname, pos);
} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
wpa_cli_exec(action_file, ctrl_ifname, pos);
+ } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
+ wpa_cli_exec(action_file, ctrl_ifname, pos);
} else if (str_match(pos, WPS_EVENT_SUCCESS)) {
wpa_cli_exec(action_file, ctrl_ifname, pos);
} else if (str_match(pos, WPS_EVENT_FAIL)) {
wpa_cli_exec(action_file, ctrl_ifname, pos);
+ } else if (str_match(pos, AP_STA_CONNECTED)) {
+ wpa_cli_exec(action_file, ctrl_ifname, pos);
+ } else if (str_match(pos, AP_STA_DISCONNECTED)) {
+ wpa_cli_exec(action_file, ctrl_ifname, pos);
} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
printf("wpa_supplicant is terminating - stop monitoring\n");
wpa_cli_quit = 1;
}
-#ifdef ANDROID_BRCM_P2P_PATCH
- else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- }
-#endif
}
@@ -2992,6 +3341,74 @@ static void wpa_cli_reconnect(void)
}
+static void cli_event(const char *str)
+{
+ const char *start, *s;
+
+ start = os_strchr(str, '>');
+ if (start == NULL)
+ return;
+
+ start++;
+
+ if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
+ s = os_strchr(start, ' ');
+ if (s == NULL)
+ return;
+ s = os_strchr(s + 1, ' ');
+ if (s == NULL)
+ return;
+ cli_txt_list_add(&bsses, s + 1);
+ return;
+ }
+
+ if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
+ s = os_strchr(start, ' ');
+ if (s == NULL)
+ return;
+ s = os_strchr(s + 1, ' ');
+ if (s == NULL)
+ return;
+ cli_txt_list_del_addr(&bsses, s + 1);
+ return;
+ }
+
+#ifdef CONFIG_P2P
+ if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
+ s = os_strstr(start, " p2p_dev_addr=");
+ if (s == NULL)
+ return;
+ cli_txt_list_add_addr(&p2p_peers, s + 14);
+ return;
+ }
+
+ if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
+ s = os_strstr(start, " p2p_dev_addr=");
+ if (s == NULL)
+ return;
+ cli_txt_list_del_addr(&p2p_peers, s + 14);
+ return;
+ }
+
+ if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
+ s = os_strchr(start, ' ');
+ if (s == NULL)
+ return;
+ cli_txt_list_add_word(&p2p_groups, s + 1);
+ return;
+ }
+
+ if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
+ s = os_strchr(start, ' ');
+ if (s == NULL)
+ return;
+ cli_txt_list_del_word(&p2p_groups, s + 1);
+ return;
+ }
+#endif /* CONFIG_P2P */
+}
+
+
static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
{
if (ctrl_conn == NULL) {
@@ -3006,6 +3423,7 @@ static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
if (action_monitor)
wpa_cli_action_process(buf);
else {
+ cli_event(buf);
if (wpa_cli_show_event(buf)) {
edit_clear_line();
printf("\r%s\n", buf);
@@ -3120,6 +3538,9 @@ static void wpa_cli_interactive(void)
eloop_run();
+ cli_txt_list_flush(&p2p_peers);
+ cli_txt_list_flush(&p2p_groups);
+ cli_txt_list_flush(&bsses);
edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
os_free(hfile);
eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresults.cpp b/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
index 459aa8c..f75f02a 100644
--- a/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
@@ -15,6 +15,7 @@
#include <cstdio>
#include "scanresults.h"
+#include "signalbar.h"
#include "wpagui.h"
#include "networkconfig.h"
@@ -33,6 +34,7 @@ ScanResults::ScanResults(QWidget *parent, const char *, bool, Qt::WFlags)
wpagui = NULL;
scanResultsWidget->setItemsExpandable(FALSE);
scanResultsWidget->setRootIsDecorated(FALSE);
+ scanResultsWidget->setItemDelegate(new SignalBar(scanResultsWidget));
}
@@ -91,7 +93,7 @@ void ScanResults::updateResults()
bssid = (*it).mid(pos);
else if ((*it).startsWith("freq="))
freq = (*it).mid(pos);
- else if ((*it).startsWith("qual="))
+ else if ((*it).startsWith("level="))
signal = (*it).mid(pos);
else if ((*it).startsWith("flags="))
flags = (*it).mid(pos);
diff --git a/wpa_supplicant/wpa_gui-qt4/signalbar.cpp b/wpa_supplicant/wpa_gui-qt4/signalbar.cpp
new file mode 100644
index 0000000..f2688d5
--- /dev/null
+++ b/wpa_supplicant/wpa_gui-qt4/signalbar.cpp
@@ -0,0 +1,64 @@
+/*
+ * wpa_gui - SignalBar class
+ * Copyright (c) 2011, Kel Modderman <kel@otaku42.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include <cstdio>
+#include <qapplication.h>
+
+#include "signalbar.h"
+
+
+SignalBar::SignalBar(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+
+SignalBar::~SignalBar()
+{
+}
+
+
+void SignalBar::paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ QStyleOptionProgressBar opts;
+ int signal;
+
+ if (index.column() != 3) {
+ QStyledItemDelegate::paint(painter, option, index);
+ return;
+ }
+
+ if (index.data().toInt() > 0)
+ signal = 0 - (256 - index.data().toInt());
+ else
+ signal = index.data().toInt();
+
+ opts.minimum = -95;
+ opts.maximum = -35;
+ if (signal < opts.minimum)
+ opts.progress = opts.minimum;
+ else if (signal > opts.maximum)
+ opts.progress = opts.maximum;
+ else
+ opts.progress = signal;
+
+ opts.text = QString::number(signal) + " dBm";
+ opts.textVisible = true;
+ opts.rect = option.rect;
+
+ QApplication::style()->drawControl(QStyle::CE_ProgressBar,
+ &opts, painter);
+}
diff --git a/wpa_supplicant/wpa_gui-qt4/signalbar.h b/wpa_supplicant/wpa_gui-qt4/signalbar.h
new file mode 100644
index 0000000..3d5dec1
--- /dev/null
+++ b/wpa_supplicant/wpa_gui-qt4/signalbar.h
@@ -0,0 +1,34 @@
+/*
+ * wpa_gui - SignalBar class
+ * Copyright (c) 2011, Kel Modderman <kel@otaku42.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef SIGNALBAR_H
+#define SIGNALBAR_H
+
+#include <QObject>
+#include <QStyledItemDelegate>
+
+class SignalBar : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ SignalBar(QObject *parent = 0);
+ ~SignalBar();
+
+ virtual void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const ;
+};
+
+#endif /* SIGNALBAR_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro b/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
index 85848d7..3c81929 100644
--- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
+++ b/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
@@ -34,6 +34,7 @@ HEADERS += wpamsg.h \
wpagui.h \
eventhistory.h \
scanresults.h \
+ signalbar.h \
userdatarequest.h \
networkconfig.h \
addinterface.h \
@@ -44,6 +45,7 @@ SOURCES += main.cpp \
wpagui.cpp \
eventhistory.cpp \
scanresults.cpp \
+ signalbar.cpp \
userdatarequest.cpp \
networkconfig.cpp \
addinterface.cpp \
diff --git a/wpa_supplicant/wpa_gui/.gitignore b/wpa_supplicant/wpa_gui/.gitignore
deleted file mode 100644
index 4df64a9..0000000
--- a/wpa_supplicant/wpa_gui/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.moc
-.obj
-.ui
diff --git a/wpa_supplicant/wpa_gui/eventhistory.ui b/wpa_supplicant/wpa_gui/eventhistory.ui
deleted file mode 100644
index 3735fb7..0000000
--- a/wpa_supplicant/wpa_gui/eventhistory.ui
+++ /dev/null
@@ -1,125 +0,0 @@
-<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
-<class>EventHistory</class>
-<widget class="QDialog">
- <property name="name">
- <cstring>EventHistory</cstring>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>533</width>
- <height>285</height>
- </rect>
- </property>
- <property name="caption">
- <string>Event history</string>
- </property>
- <vbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QListView">
- <column>
- <property name="text">
- <string>Timestamp</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Message</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <property name="name">
- <cstring>eventListView</cstring>
- </property>
- <property name="sizePolicy">
- <sizepolicy>
- <hsizetype>7</hsizetype>
- <vsizetype>7</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="resizePolicy">
- <enum>Manual</enum>
- </property>
- <property name="selectionMode">
- <enum>NoSelection</enum>
- </property>
- <property name="resizeMode">
- <enum>LastColumn</enum>
- </property>
- </widget>
- <widget class="QLayoutWidget">
- <property name="name">
- <cstring>layout30</cstring>
- </property>
- <hbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <spacer>
- <property name="name">
- <cstring>spacer3</cstring>
- </property>
- <property name="orientation">
- <enum>Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>Expanding</enum>
- </property>
- <property name="sizeHint">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- <widget class="QPushButton">
- <property name="name">
- <cstring>closeButton</cstring>
- </property>
- <property name="text">
- <string>Close</string>
- </property>
- </widget>
- </hbox>
- </widget>
- </vbox>
-</widget>
-<connections>
- <connection>
- <sender>closeButton</sender>
- <signal>clicked()</signal>
- <receiver>EventHistory</receiver>
- <slot>close()</slot>
- </connection>
-</connections>
-<includes>
- <include location="local" impldecl="in declaration">wpamsg.h</include>
- <include location="local" impldecl="in implementation">eventhistory.ui.h</include>
-</includes>
-<slots>
- <slot>addEvents( WpaMsgList msgs )</slot>
- <slot>addEvent( WpaMsg msg )</slot>
-</slots>
-<functions>
- <function access="private" specifier="non virtual">init()</function>
- <function access="private" specifier="non virtual">destroy()</function>
-</functions>
-<pixmapinproject/>
-<layoutdefaults spacing="6" margin="11"/>
-</UI>
diff --git a/wpa_supplicant/wpa_gui/eventhistory.ui.h b/wpa_supplicant/wpa_gui/eventhistory.ui.h
deleted file mode 100644
index cb2caab..0000000
--- a/wpa_supplicant/wpa_gui/eventhistory.ui.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-void EventHistory::init()
-{
-}
-
-
-void EventHistory::destroy()
-{
-}
-
-
-void EventHistory::addEvents(WpaMsgList msgs)
-{
- WpaMsgList::iterator it;
- for (it = msgs.begin(); it != msgs.end(); it++) {
- addEvent(*it);
- }
-}
-
-
-void EventHistory::addEvent(WpaMsg msg)
-{
- Q3ListViewItem *item;
- item = new Q3ListViewItem(eventListView,
- msg.getTimestamp().toString("yyyy-MM-dd hh:mm:ss.zzz"),
- msg.getMsg());
- if (item == NULL)
- return;
- eventListView->setSelected(item, false);
-}
diff --git a/wpa_supplicant/wpa_gui/main.cpp b/wpa_supplicant/wpa_gui/main.cpp
deleted file mode 100644
index a78473a..0000000
--- a/wpa_supplicant/wpa_gui/main.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifdef CONFIG_NATIVE_WINDOWS
-#include <winsock.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
-#include <qapplication.h>
-#include "wpagui.h"
-
-int main( int argc, char ** argv )
-{
- QApplication a( argc, argv );
- WpaGui w;
- int ret;
-
-#ifdef CONFIG_NATIVE_WINDOWS
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
- printf("Could not find a usable WinSock.dll\n");
- return -1;
- }
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- w.show();
- a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
- ret = a.exec();
-
-#ifdef CONFIG_NATIVE_WINDOWS
- WSACleanup();
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- return ret;
-}
diff --git a/wpa_supplicant/wpa_gui/networkconfig.ui b/wpa_supplicant/wpa_gui/networkconfig.ui
deleted file mode 100644
index 019ecf7..0000000
--- a/wpa_supplicant/wpa_gui/networkconfig.ui
+++ /dev/null
@@ -1,475 +0,0 @@
-<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
-<class>NetworkConfig</class>
-<widget class="QDialog">
- <property name="name">
- <cstring>NetworkConfig</cstring>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>380</width>
- <height>430</height>
- </rect>
- </property>
- <property name="caption">
- <string>NetworkConfig</string>
- </property>
- <grid>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QPushButton" row="1" column="3">
- <property name="name">
- <cstring>cancelButton</cstring>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- <widget class="QFrame" row="0" column="0" rowspan="1" colspan="4">
- <property name="name">
- <cstring>frame9</cstring>
- </property>
- <property name="frameShape">
- <enum>StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>Raised</enum>
- </property>
- <grid>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QLabel" row="0" column="0">
- <property name="name">
- <cstring>textLabel0</cstring>
- </property>
- <property name="text">
- <string>SSID</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="0" column="1">
- <property name="name">
- <cstring>ssidEdit</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- <property name="toolTip" stdset="0">
- <string>Network name (Service Set IDentifier)</string>
- </property>
- </widget>
- <widget class="QLabel" row="1" column="0">
- <property name="name">
- <cstring>textLabel1</cstring>
- </property>
- <property name="text">
- <string>Network ID</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="1" column="1">
- <property name="name">
- <cstring>idstrEdit</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- <property name="toolTip" stdset="0">
- <string>Network Identification String</string>
- </property>
- </widget>
- <widget class="QLabel" row="2" column="0">
- <property name="name">
- <cstring>textLabel2</cstring>
- </property>
- <property name="text">
- <string>Authentication</string>
- </property>
- </widget>
- <widget class="QComboBox" row="2" column="1">
- <item>
- <property name="text">
- <string>Plaintext or static WEP</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>IEEE 802.1X</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>WPA-Personal (PSK)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>WPA-Enterprise (EAP)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>WPA2-Personal (PSK)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>WPA2-Enterprise (EAP)</string>
- </property>
- </item>
- <property name="name">
- <cstring>authSelect</cstring>
- </property>
- </widget>
- <widget class="QLabel" row="3" column="0">
- <property name="name">
- <cstring>textLabel3</cstring>
- </property>
- <property name="text">
- <string>Encryption</string>
- </property>
- </widget>
- <widget class="QComboBox" row="3" column="1">
- <item>
- <property name="text">
- <string>None</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>WEP</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>TKIP</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>CCMP</string>
- </property>
- </item>
- <property name="name">
- <cstring>encrSelect</cstring>
- </property>
- </widget>
- <widget class="QLabel" row="4" column="0">
- <property name="name">
- <cstring>textLabel4</cstring>
- </property>
- <property name="text">
- <string>PSK</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="4" column="1">
- <property name="name">
- <cstring>pskEdit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="echoMode">
- <enum>Password</enum>
- </property>
- <property name="toolTip" stdset="0">
- <string>WPA/WPA2 pre-shared key or passphrase</string>
- </property>
- <property name="whatsThis" stdset="0">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="5" column="0">
- <property name="name">
- <cstring>textLabel5</cstring>
- </property>
- <property name="text">
- <string>EAP method</string>
- </property>
- </widget>
- <widget class="QComboBox" row="5" column="1">
- <property name="name">
- <cstring>eapSelect</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- <widget class="QLabel" row="6" column="0">
- <property name="name">
- <cstring>textLabel6</cstring>
- </property>
- <property name="text">
- <string>Identity</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="6" column="1">
- <property name="name">
- <cstring>identityEdit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="toolTip" stdset="0">
- <string>Username/Identity for EAP methods</string>
- </property>
- </widget>
- <widget class="QLabel" row="7" column="0">
- <property name="name">
- <cstring>textLabel7</cstring>
- </property>
- <property name="text">
- <string>Password</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="7" column="1">
- <property name="name">
- <cstring>passwordEdit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="echoMode">
- <enum>Password</enum>
- </property>
- <property name="toolTip" stdset="0">
- <string>Password for EAP methods</string>
- </property>
- </widget>
- <widget class="QLabel" row="8" column="0">
- <property name="name">
- <cstring>textLabel1_2</cstring>
- </property>
- <property name="text">
- <string>CA certificate</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="8" column="1">
- <property name="name">
- <cstring>cacertEdit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- <widget class="QButtonGroup" row="9" column="0" rowspan="1" colspan="2">
- <property name="name">
- <cstring>buttonGroup1</cstring>
- </property>
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>WEP keys</string>
- </property>
- <grid>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QRadioButton" row="0" column="0">
- <property name="name">
- <cstring>wep0Radio</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>key 0</string>
- </property>
- </widget>
- <widget class="QRadioButton" row="1" column="0">
- <property name="name">
- <cstring>wep1Radio</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>key 1</string>
- </property>
- </widget>
- <widget class="QRadioButton" row="3" column="0">
- <property name="name">
- <cstring>wep3Radio</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>key 3</string>
- </property>
- </widget>
- <widget class="QRadioButton" row="2" column="0">
- <property name="name">
- <cstring>wep2Radio</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>key 2</string>
- </property>
- </widget>
- <widget class="QLineEdit" row="0" column="1">
- <property name="name">
- <cstring>wep0Edit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- <widget class="QLineEdit" row="1" column="1">
- <property name="name">
- <cstring>wep1Edit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- <widget class="QLineEdit" row="2" column="1">
- <property name="name">
- <cstring>wep2Edit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- <widget class="QLineEdit" row="3" column="1">
- <property name="name">
- <cstring>wep3Edit</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </grid>
- </widget>
- </grid>
- </widget>
- <spacer row="1" column="0">
- <property name="name">
- <cstring>spacer5</cstring>
- </property>
- <property name="orientation">
- <enum>Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>Expanding</enum>
- </property>
- <property name="sizeHint">
- <size>
- <width>130</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- <widget class="QPushButton" row="1" column="1">
- <property name="name">
- <cstring>addButton</cstring>
- </property>
- <property name="text">
- <string>Add</string>
- </property>
- </widget>
- <widget class="QPushButton" row="1" column="2">
- <property name="name">
- <cstring>removeButton</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </grid>
-</widget>
-<connections>
- <connection>
- <sender>authSelect</sender>
- <signal>activated(int)</signal>
- <receiver>NetworkConfig</receiver>
- <slot>authChanged(int)</slot>
- </connection>
- <connection>
- <sender>cancelButton</sender>
- <signal>clicked()</signal>
- <receiver>NetworkConfig</receiver>
- <slot>close()</slot>
- </connection>
- <connection>
- <sender>addButton</sender>
- <signal>clicked()</signal>
- <receiver>NetworkConfig</receiver>
- <slot>addNetwork()</slot>
- </connection>
- <connection>
- <sender>encrSelect</sender>
- <signal>activated(const QString&amp;)</signal>
- <receiver>NetworkConfig</receiver>
- <slot>encrChanged(const QString&amp;)</slot>
- </connection>
- <connection>
- <sender>removeButton</sender>
- <signal>clicked()</signal>
- <receiver>NetworkConfig</receiver>
- <slot>removeNetwork()</slot>
- </connection>
-</connections>
-<tabstops>
- <tabstop>ssidEdit</tabstop>
- <tabstop>idstrEdit</tabstop>
- <tabstop>authSelect</tabstop>
- <tabstop>encrSelect</tabstop>
- <tabstop>pskEdit</tabstop>
- <tabstop>eapSelect</tabstop>
- <tabstop>identityEdit</tabstop>
- <tabstop>passwordEdit</tabstop>
- <tabstop>cacertEdit</tabstop>
- <tabstop>wep0Radio</tabstop>
- <tabstop>wep1Radio</tabstop>
- <tabstop>wep2Radio</tabstop>
- <tabstop>wep3Radio</tabstop>
- <tabstop>wep0Edit</tabstop>
- <tabstop>wep1Edit</tabstop>
- <tabstop>wep2Edit</tabstop>
- <tabstop>wep3Edit</tabstop>
- <tabstop>addButton</tabstop>
- <tabstop>removeButton</tabstop>
- <tabstop>cancelButton</tabstop>
-</tabstops>
-<includes>
- <include location="global" impldecl="in declaration">qlistview.h</include>
- <include location="global" impldecl="in implementation">qmessagebox.h</include>
- <include location="local" impldecl="in implementation">wpagui.h</include>
- <include location="local" impldecl="in implementation">networkconfig.ui.h</include>
-</includes>
-<forwards>
- <forward>class WpaGui;</forward>
-</forwards>
-<variables>
- <variable access="private">WpaGui *wpagui;</variable>
- <variable access="private">int edit_network_id;</variable>
- <variable access="private">bool new_network;</variable>
-</variables>
-<slots>
- <slot>authChanged( int sel )</slot>
- <slot>addNetwork()</slot>
- <slot>encrChanged( const QString &amp; sel )</slot>
- <slot>writeWepKey( int network_id, QLineEdit * edit, int id )</slot>
- <slot>removeNetwork()</slot>
-</slots>
-<functions>
- <function access="private" specifier="non virtual">init()</function>
- <function>paramsFromScanResults( QListViewItem * sel )</function>
- <function>setWpaGui( WpaGui * _wpagui )</function>
- <function returnType="int">setNetworkParam( int id, const char * field, const char * value, bool quote )</function>
- <function access="private">wepEnabled( bool enabled )</function>
- <function>paramsFromConfig( int network_id )</function>
- <function>newNetwork()</function>
- <function access="private">getEapCapa()</function>
-</functions>
-<pixmapinproject/>
-<layoutdefaults spacing="6" margin="11"/>
-</UI>
diff --git a/wpa_supplicant/wpa_gui/networkconfig.ui.h b/wpa_supplicant/wpa_gui/networkconfig.ui.h
deleted file mode 100644
index 501d5d2..0000000
--- a/wpa_supplicant/wpa_gui/networkconfig.ui.h
+++ /dev/null
@@ -1,552 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-#include <stdlib.h>
-
-enum {
- AUTH_NONE = 0,
- AUTH_IEEE8021X = 1,
- AUTH_WPA_PSK = 2,
- AUTH_WPA_EAP = 3,
- AUTH_WPA2_PSK = 4,
- AUTH_WPA2_EAP = 5
-};
-
-#define WPA_GUI_KEY_DATA "[key is configured]"
-
-void NetworkConfig::init()
-{
- wpagui = NULL;
- new_network = false;
-}
-
-void NetworkConfig::paramsFromScanResults(Q3ListViewItem *sel)
-{
- new_network = true;
-
- /* SSID BSSID frequency signal flags */
- setCaption(sel->text(0));
- ssidEdit->setText(sel->text(0));
-
- QString flags = sel->text(4);
- int auth, encr = 0;
- if (flags.find("[WPA2-EAP") >= 0)
- auth = AUTH_WPA2_EAP;
- else if (flags.find("[WPA-EAP") >= 0)
- auth = AUTH_WPA_EAP;
- else if (flags.find("[WPA2-PSK") >= 0)
- auth = AUTH_WPA2_PSK;
- else if (flags.find("[WPA-PSK") >= 0)
- auth = AUTH_WPA_PSK;
- else
- auth = AUTH_NONE;
-
- if (flags.find("-CCMP") >= 0)
- encr = 1;
- else if (flags.find("-TKIP") >= 0)
- encr = 0;
- else if (flags.find("WEP") >= 0)
- encr = 1;
- else
- encr = 0;
-
- authSelect->setCurrentItem(auth);
- authChanged(auth);
- encrSelect->setCurrentItem(encr);
-
- getEapCapa();
-}
-
-
-void NetworkConfig::authChanged(int sel)
-{
- pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
- bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
- sel == AUTH_WPA2_EAP;
- eapSelect->setEnabled(eap);
- identityEdit->setEnabled(eap);
- passwordEdit->setEnabled(eap);
- cacertEdit->setEnabled(eap);
-
- while (encrSelect->count())
- encrSelect->removeItem(0);
-
- if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
- encrSelect->insertItem("None");
- encrSelect->insertItem("WEP");
- encrSelect->setCurrentItem(sel == AUTH_NONE ? 0 : 1);
- } else {
- encrSelect->insertItem("TKIP");
- encrSelect->insertItem("CCMP");
- encrSelect->setCurrentItem((sel == AUTH_WPA2_PSK ||
- sel == AUTH_WPA2_EAP) ? 1 : 0);
- }
-
- wepEnabled(sel == AUTH_IEEE8021X);
-}
-
-
-void NetworkConfig::addNetwork()
-{
- char reply[10], cmd[256];
- size_t reply_len;
- int id;
- int psklen = pskEdit->text().length();
- int auth = authSelect->currentItem();
-
- if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
- if (psklen < 8 || psklen > 64) {
- QMessageBox::warning(this, "wpa_gui", "WPA-PSK requires a passphrase "
- "of 8 to 63 characters\n"
- "or 64 hex digit PSK");
- return;
- }
- }
-
- if (wpagui == NULL)
- return;
-
- memset(reply, 0, sizeof(reply));
- reply_len = sizeof(reply) - 1;
-
- if (new_network) {
- wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
- if (reply[0] == 'F') {
- QMessageBox::warning(this, "wpa_gui", "Failed to add network to wpa_supplicant\n"
- "configuration.");
- return;
- }
- id = atoi(reply);
- } else {
- id = edit_network_id;
- }
-
- setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
-
- if (idstrEdit->isEnabled())
- setNetworkParam(id, "id_str", idstrEdit->text().ascii(), true);
-
- const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
- switch (auth) {
- case AUTH_NONE:
- key_mgmt = "NONE";
- break;
- case AUTH_IEEE8021X:
- key_mgmt = "IEEE8021X";
- break;
- case AUTH_WPA_PSK:
- key_mgmt = "WPA-PSK";
- proto = "WPA";
- break;
- case AUTH_WPA_EAP:
- key_mgmt = "WPA-EAP";
- proto = "WPA";
- break;
- case AUTH_WPA2_PSK:
- key_mgmt = "WPA-PSK";
- proto = "WPA2";
- break;
- case AUTH_WPA2_EAP:
- key_mgmt = "WPA-EAP";
- proto = "WPA2";
- break;
- }
-
- if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
- auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
- int encr = encrSelect->currentItem();
- if (encr == 0)
- pairwise = "TKIP";
- else
- pairwise = "CCMP";
- }
-
- if (proto)
- setNetworkParam(id, "proto", proto, false);
- if (key_mgmt)
- setNetworkParam(id, "key_mgmt", key_mgmt, false);
- if (pairwise) {
- setNetworkParam(id, "pairwise", pairwise, false);
- setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
- }
- if (pskEdit->isEnabled() &&
- strcmp(pskEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
- setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
- if (eapSelect->isEnabled())
- setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);
- if (identityEdit->isEnabled())
- setNetworkParam(id, "identity", identityEdit->text().ascii(), true);
- if (passwordEdit->isEnabled() &&
- strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
- setNetworkParam(id, "password", passwordEdit->text().ascii(), true);
- if (cacertEdit->isEnabled())
- setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true);
- writeWepKey(id, wep0Edit, 0);
- writeWepKey(id, wep1Edit, 1);
- writeWepKey(id, wep2Edit, 2);
- writeWepKey(id, wep3Edit, 3);
-
- if (wep0Radio->isEnabled() && wep0Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "0", false);
- else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "1", false);
- else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "2", false);
- else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "3", false);
-
- snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (strncmp(reply, "OK", 2) != 0) {
- QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n"
- "configuration.");
- /* Network was added, so continue anyway */
- }
- wpagui->triggerUpdate();
- wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
-
- close();
-}
-
-
-void NetworkConfig::setWpaGui( WpaGui *_wpagui )
-{
- wpagui = _wpagui;
-}
-
-
-int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote)
-{
- char reply[10], cmd[256];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
- id, field, quote ? "\"" : "", value, quote ? "\"" : "");
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
-}
-
-
-void NetworkConfig::encrChanged( const QString &sel )
-{
- wepEnabled(sel.find("WEP") == 0);
-}
-
-
-void NetworkConfig::wepEnabled( bool enabled )
-{
- wep0Edit->setEnabled(enabled);
- wep1Edit->setEnabled(enabled);
- wep2Edit->setEnabled(enabled);
- wep3Edit->setEnabled(enabled);
- wep0Radio->setEnabled(enabled);
- wep1Radio->setEnabled(enabled);
- wep2Radio->setEnabled(enabled);
- wep3Radio->setEnabled(enabled);
-}
-
-
-void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id )
-{
- char buf[10];
- bool hex;
- const char *txt, *pos;
- size_t len;
-
- if (!edit->isEnabled() || edit->text().isEmpty())
- return;
-
- /*
- * Assume hex key if only hex characters are present and length matches
- * with 40, 104, or 128-bit key
- */
- txt = edit->text().ascii();
- if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
- return;
- len = strlen(txt);
- if (len == 0)
- return;
- pos = txt;
- hex = true;
- while (*pos) {
- if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') ||
- (*pos >= 'A' && *pos <= 'F'))) {
- hex = false;
- break;
- }
- pos++;
- }
- if (hex && len != 10 && len != 26 && len != 32)
- hex = false;
- snprintf(buf, sizeof(buf), "wep_key%d", id);
- setNetworkParam(network_id, buf, txt, !hex);
-}
-
-
-static int key_value_isset(const char *reply, size_t reply_len)
-{
- return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
-}
-
-
-void NetworkConfig::paramsFromConfig( int network_id )
-{
- int i, res;
-
- edit_network_id = network_id;
- getEapCapa();
-
- char reply[1024], cmd[256], *pos;
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- ssidEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- idstrEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
- reply_len = sizeof(reply) - 1;
- int wpa = 0;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
- wpa = 2;
- else if (strstr(reply, "WPA"))
- wpa = 1;
- }
-
- int auth = AUTH_NONE, encr = 0;
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "WPA-EAP"))
- auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
- else if (strstr(reply, "WPA-PSK"))
- auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
- else if (strstr(reply, "IEEE8021X")) {
- auth = AUTH_IEEE8021X;
- encr = 1;
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "CCMP") && auth != AUTH_NONE)
- encr = 1;
- else if (strstr(reply, "TKIP"))
- encr = 0;
- else if (strstr(reply, "WEP"))
- encr = 1;
- else
- encr = 0;
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
- reply_len = sizeof(reply) - 1;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- pskEdit->setText(reply + 1);
- } else if (res >= 0 && key_value_isset(reply, reply_len)) {
- pskEdit->setText(WPA_GUI_KEY_DATA);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- identityEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
- reply_len = sizeof(reply) - 1;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (res >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- passwordEdit->setText(reply + 1);
- } else if (res >= 0 && key_value_isset(reply, reply_len)) {
- passwordEdit->setText(WPA_GUI_KEY_DATA);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- cacertEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
- reply[reply_len] = '\0';
- for (i = 0; i < eapSelect->count(); i++) {
- if (eapSelect->text(i).compare(reply) == 0) {
- eapSelect->setCurrentItem(i);
- break;
- }
- }
- }
-
- for (i = 0; i < 4; i++) {
- QLineEdit *wepEdit;
- switch (i) {
- default:
- case 0:
- wepEdit = wep0Edit;
- break;
- case 1:
- wepEdit = wep1Edit;
- break;
- case 2:
- wepEdit = wep2Edit;
- break;
- case 3:
- wepEdit = wep3Edit;
- break;
- }
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i);
- reply_len = sizeof(reply) - 1;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
- encr = 1;
-
- wepEdit->setText(reply + 1);
- } else if (res >= 0 && key_value_isset(reply, reply_len)) {
- if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
- encr = 1;
- wepEdit->setText(WPA_GUI_KEY_DATA);
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
- reply[reply_len] = '\0';
- switch (atoi(reply)) {
- case 0:
- wep0Radio->setChecked(true);
- break;
- case 1:
- wep1Radio->setChecked(true);
- break;
- case 2:
- wep2Radio->setChecked(true);
- break;
- case 3:
- wep3Radio->setChecked(true);
- break;
- }
- }
-
- authSelect->setCurrentItem(auth);
- authChanged(auth);
- encrSelect->setCurrentItem(encr);
- if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
- wepEnabled(encr == 1);
-
- removeButton->setEnabled(true);
- addButton->setText("Save");
-}
-
-
-void NetworkConfig::removeNetwork()
-{
- char reply[10], cmd[256];
- size_t reply_len;
-
- if (QMessageBox::information(this, "wpa_gui",
- "This will permanently remove the network\n"
- "from the configuration. Do you really want\n"
- "to remove this network?", "Yes", "No") != 0)
- return;
-
- snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (strncmp(reply, "OK", 2) != 0) {
- QMessageBox::warning(this, "wpa_gui",
- "Failed to remove network from wpa_supplicant\n"
- "configuration.");
- } else {
- wpagui->triggerUpdate();
- wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
- }
-
- close();
-}
-
-
-void NetworkConfig::newNetwork()
-{
- new_network = true;
- getEapCapa();
-}
-
-
-void NetworkConfig::getEapCapa()
-{
- char reply[256];
- size_t reply_len;
-
- if (wpagui == NULL)
- return;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
-
- QString res(reply);
- QStringList types = QStringList::split(QChar(' '), res);
- eapSelect->insertStringList(types);
-}
diff --git a/wpa_supplicant/wpa_gui/scanresults.ui b/wpa_supplicant/wpa_gui/scanresults.ui
deleted file mode 100644
index dea305b..0000000
--- a/wpa_supplicant/wpa_gui/scanresults.ui
+++ /dev/null
@@ -1,179 +0,0 @@
-<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
-<class>ScanResults</class>
-<widget class="QDialog">
- <property name="name">
- <cstring>ScanResults</cstring>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>452</width>
- <height>225</height>
- </rect>
- </property>
- <property name="caption">
- <string>Scan results</string>
- </property>
- <vbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QListView">
- <column>
- <property name="text">
- <string>SSID</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <column>
- <property name="text">
- <string>BSSID</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <column>
- <property name="text">
- <string>frequency</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <column>
- <property name="text">
- <string>signal</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <column>
- <property name="text">
- <string>flags</string>
- </property>
- <property name="clickable">
- <bool>true</bool>
- </property>
- <property name="resizable">
- <bool>true</bool>
- </property>
- </column>
- <property name="name">
- <cstring>scanResultsView</cstring>
- </property>
- <property name="frameShape">
- <enum>StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>Sunken</enum>
- </property>
- </widget>
- <widget class="QLayoutWidget">
- <property name="name">
- <cstring>layout24</cstring>
- </property>
- <hbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <spacer>
- <property name="name">
- <cstring>spacer6</cstring>
- </property>
- <property name="orientation">
- <enum>Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>Expanding</enum>
- </property>
- <property name="sizeHint">
- <size>
- <width>50</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- <widget class="QPushButton">
- <property name="name">
- <cstring>scanButton</cstring>
- </property>
- <property name="text">
- <string>Scan</string>
- </property>
- </widget>
- <widget class="QPushButton">
- <property name="name">
- <cstring>closeButton</cstring>
- </property>
- <property name="text">
- <string>Close</string>
- </property>
- </widget>
- </hbox>
- </widget>
- </vbox>
-</widget>
-<connections>
- <connection>
- <sender>closeButton</sender>
- <signal>clicked()</signal>
- <receiver>ScanResults</receiver>
- <slot>close()</slot>
- </connection>
- <connection>
- <sender>scanButton</sender>
- <signal>clicked()</signal>
- <receiver>ScanResults</receiver>
- <slot>scanRequest()</slot>
- </connection>
- <connection>
- <sender>scanResultsView</sender>
- <signal>doubleClicked(QListViewItem*)</signal>
- <receiver>ScanResults</receiver>
- <slot>bssSelected(QListViewItem*)</slot>
- </connection>
-</connections>
-<includes>
- <include location="local" impldecl="in implementation">common/wpa_ctrl.h</include>
- <include location="local" impldecl="in implementation">wpagui.h</include>
- <include location="local" impldecl="in implementation">networkconfig.h</include>
- <include location="local" impldecl="in implementation">scanresults.ui.h</include>
-</includes>
-<forwards>
- <forward>class WpaGui;</forward>
-</forwards>
-<variables>
- <variable access="private">WpaGui *wpagui;</variable>
- <variable access="private">QTimer *timer;</variable>
-</variables>
-<slots>
- <slot>setWpaGui( WpaGui * _wpagui )</slot>
- <slot>updateResults()</slot>
- <slot>scanRequest()</slot>
- <slot>getResults()</slot>
- <slot>bssSelected( QListViewItem * sel )</slot>
-</slots>
-<functions>
- <function access="private" specifier="non virtual">init()</function>
- <function access="private" specifier="non virtual">destroy()</function>
-</functions>
-<pixmapinproject/>
-<layoutdefaults spacing="6" margin="11"/>
-</UI>
diff --git a/wpa_supplicant/wpa_gui/scanresults.ui.h b/wpa_supplicant/wpa_gui/scanresults.ui.h
deleted file mode 100644
index 530d2e6..0000000
--- a/wpa_supplicant/wpa_gui/scanresults.ui.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-void ScanResults::init()
-{
- wpagui = NULL;
-}
-
-
-void ScanResults::destroy()
-{
- delete timer;
-}
-
-
-void ScanResults::setWpaGui(WpaGui *_wpagui)
-{
- wpagui = _wpagui;
- updateResults();
-
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), SLOT(getResults()));
- timer->start(10000, FALSE);
-}
-
-
-void ScanResults::updateResults()
-{
- char reply[8192];
- size_t reply_len;
-
- if (wpagui == NULL)
- return;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("SCAN_RESULTS", reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
-
- scanResultsView->clear();
-
- QString res(reply);
- QStringList lines = QStringList::split(QChar('\n'), res);
- bool first = true;
- for (QStringList::Iterator it = lines.begin(); it != lines.end(); it++) {
- if (first) {
- first = false;
- continue;
- }
-
- QStringList cols = QStringList::split(QChar('\t'), *it, true);
- QString ssid, bssid, freq, signal, flags;
- bssid = cols.count() > 0 ? cols[0] : "";
- freq = cols.count() > 1 ? cols[1] : "";
- signal = cols.count() > 2 ? cols[2] : "";
- flags = cols.count() > 3 ? cols[3] : "";
- ssid = cols.count() > 4 ? cols[4] : "";
- new Q3ListViewItem(scanResultsView, ssid, bssid, freq, signal, flags);
- }
-}
-
-
-void ScanResults::scanRequest()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (wpagui == NULL)
- return;
-
- wpagui->ctrlRequest("SCAN", reply, &reply_len);
-}
-
-
-void ScanResults::getResults()
-{
- updateResults();
-}
-
-
-
-
-void ScanResults::bssSelected( Q3ListViewItem * sel )
-{
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(wpagui);
- nc->paramsFromScanResults(sel);
- nc->show();
- nc->exec();
-}
diff --git a/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling b/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling
deleted file mode 100755
index e173b00..0000000
--- a/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# qmake seems to be forcing include and lib paths from the original build
-# and I have no idea how to change these. For now, just override the
-# directories in the Makefile.Release file after qmake run.
-
-qmake -spec /q/jm/qt4-win/4.0.0/mkspecs/win32-g++ wpa_gui.pro -o Makefile
-cat Makefile.Release |
- sed s%qt4/lib%qt4-win/4.0.0/lib%g |
- sed s%qt4/include%qt4-win/4.0.0/include%g > tmp.Makefile.Release &&
-mv -f tmp.Makefile.Release Makefile.Release
diff --git a/wpa_supplicant/wpa_gui/userdatarequest.ui b/wpa_supplicant/wpa_gui/userdatarequest.ui
deleted file mode 100644
index 6106b1e..0000000
--- a/wpa_supplicant/wpa_gui/userdatarequest.ui
+++ /dev/null
@@ -1,163 +0,0 @@
-<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
-<class>UserDataRequest</class>
-<widget class="QDialog">
- <property name="name">
- <cstring>UserDataRequest</cstring>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>216</width>
- <height>103</height>
- </rect>
- </property>
- <property name="caption">
- <string>Authentication credentials required</string>
- </property>
- <property name="sizeGripEnabled">
- <bool>true</bool>
- </property>
- <vbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QLabel">
- <property name="name">
- <cstring>queryInfo</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLayoutWidget">
- <property name="name">
- <cstring>layout28</cstring>
- </property>
- <hbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QLabel">
- <property name="name">
- <cstring>queryField</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLineEdit">
- <property name="name">
- <cstring>queryEdit</cstring>
- </property>
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="echoMode">
- <enum>Password</enum>
- </property>
- </widget>
- </hbox>
- </widget>
- <widget class="QLayoutWidget">
- <property name="name">
- <cstring>layout27</cstring>
- </property>
- <hbox>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <spacer>
- <property name="name">
- <cstring>spacer4</cstring>
- </property>
- <property name="orientation">
- <enum>Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>Expanding</enum>
- </property>
- <property name="sizeHint">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- <widget class="QPushButton">
- <property name="name">
- <cstring>buttonOk</cstring>
- </property>
- <property name="text">
- <string>&amp;OK</string>
- </property>
- <property name="accel">
- <string></string>
- </property>
- <property name="autoDefault">
- <bool>true</bool>
- </property>
- <property name="default">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QPushButton">
- <property name="name">
- <cstring>buttonCancel</cstring>
- </property>
- <property name="text">
- <string>&amp;Cancel</string>
- </property>
- <property name="accel">
- <string></string>
- </property>
- <property name="autoDefault">
- <bool>true</bool>
- </property>
- </widget>
- </hbox>
- </widget>
- </vbox>
-</widget>
-<connections>
- <connection>
- <sender>buttonOk</sender>
- <signal>clicked()</signal>
- <receiver>UserDataRequest</receiver>
- <slot>sendReply()</slot>
- </connection>
- <connection>
- <sender>buttonCancel</sender>
- <signal>clicked()</signal>
- <receiver>UserDataRequest</receiver>
- <slot>reject()</slot>
- </connection>
- <connection>
- <sender>queryEdit</sender>
- <signal>returnPressed()</signal>
- <receiver>UserDataRequest</receiver>
- <slot>sendReply()</slot>
- </connection>
-</connections>
-<includes>
- <include location="local" impldecl="in implementation">common/wpa_ctrl.h</include>
- <include location="local" impldecl="in implementation">wpagui.h</include>
- <include location="local" impldecl="in implementation">userdatarequest.ui.h</include>
-</includes>
-<forwards>
- <forward>class WpaGui;</forward>
-</forwards>
-<variables>
- <variable access="private">WpaGui *wpagui;</variable>
- <variable access="private">int networkid;</variable>
- <variable access="private">QString field;</variable>
-</variables>
-<slots>
- <slot>sendReply()</slot>
-</slots>
-<functions>
- <function specifier="non virtual" returnType="int">setParams( WpaGui * _wpagui, const char * reqMsg )</function>
-</functions>
-<pixmapinproject/>
-<layoutdefaults spacing="6" margin="11"/>
-</UI>
diff --git a/wpa_supplicant/wpa_gui/userdatarequest.ui.h b/wpa_supplicant/wpa_gui/userdatarequest.ui.h
deleted file mode 100644
index 66d4478..0000000
--- a/wpa_supplicant/wpa_gui/userdatarequest.ui.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-#include <stdlib.h>
-
-int UserDataRequest::setParams(WpaGui *_wpagui, const char *reqMsg)
-{
- char *tmp, *pos, *pos2;
- wpagui = _wpagui;
- tmp = strdup(reqMsg);
- if (tmp == NULL)
- return -1;
- pos = strchr(tmp, '-');
- if (pos == NULL) {
- free(tmp);
- return -1;
- }
- *pos++ = '\0';
- field = tmp;
- pos2 = strchr(pos, ':');
- if (pos2 == NULL) {
- free(tmp);
- return -1;
- }
- *pos2++ = '\0';
-
- networkid = atoi(pos);
- queryInfo->setText(pos2);
- if (strcmp(tmp, "PASSWORD") == 0) {
- queryField->setText("Password: ");
- queryEdit->setEchoMode(QLineEdit::Password);
- } else if (strcmp(tmp, "NEW_PASSWORD") == 0) {
- queryField->setText("New password: ");
- queryEdit->setEchoMode(QLineEdit::Password);
- } else if (strcmp(tmp, "IDENTITY") == 0)
- queryField->setText("Identity: ");
- else if (strcmp(tmp, "PASSPHRASE") == 0) {
- queryField->setText("Private key passphrase: ");
- queryEdit->setEchoMode(QLineEdit::Password);
- } else
- queryField->setText(field + ":");
- free(tmp);
-
- return 0;
-}
-
-
-void UserDataRequest::sendReply()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (wpagui == NULL) {
- reject();
- return;
- }
-
- QString cmd = QString(WPA_CTRL_RSP) + field + '-' +
- QString::number(networkid) + ':' +
- queryEdit->text();
- wpagui->ctrlRequest(cmd.ascii(), reply, &reply_len);
- accept();
-}
diff --git a/wpa_supplicant/wpa_gui/wpa_gui.pro b/wpa_supplicant/wpa_gui/wpa_gui.pro
deleted file mode 100644
index a42a4ac..0000000
--- a/wpa_supplicant/wpa_gui/wpa_gui.pro
+++ /dev/null
@@ -1,50 +0,0 @@
-TEMPLATE = app
-LANGUAGE = C++
-
-CONFIG += qt warn_on release
-
-DEFINES += CONFIG_CTRL_IFACE
-
-win32 {
- LIBS += -lws2_32 -static
- DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
- SOURCES += ../../src/utils/os_win32.c
-} else:win32-g++ {
- # cross compilation to win32
- LIBS += -lws2_32 -static
- DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
- SOURCES += ../../src/utils/os_win32.c
-} else {
- DEFINES += CONFIG_CTRL_IFACE_UNIX
- SOURCES += ../../src/utils/os_unix.c
-}
-
-INCLUDEPATH += . .. ../../src ../../src/utils
-
-HEADERS += wpamsg.h
-
-SOURCES += main.cpp \
- ../../src/common/wpa_ctrl.c
-
-FORMS = wpagui.ui \
- eventhistory.ui \
- scanresults.ui \
- userdatarequest.ui \
- networkconfig.ui
-
-
-unix {
- UI_DIR = .ui
- MOC_DIR = .moc
- OBJECTS_DIR = .obj
-}
-
-qtver = $$[QT_VERSION]
-isEmpty( qtver ) {
- message(Compiling for Qt 3.x)
- DEFINES += Q3ListViewItem=QListViewItem
-} else {
- message(Compiling for Qt $$qtver)
- QT += qt3support
- CONFIG += uic3
-}
diff --git a/wpa_supplicant/wpa_gui/wpagui.ui b/wpa_supplicant/wpa_gui/wpagui.ui
deleted file mode 100644
index b49d96b..0000000
--- a/wpa_supplicant/wpa_gui/wpagui.ui
+++ /dev/null
@@ -1,471 +0,0 @@
-<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
-<class>WpaGui</class>
-<widget class="QMainWindow">
- <property name="name">
- <cstring>WpaGui</cstring>
- </property>
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>279</width>
- <height>308</height>
- </rect>
- </property>
- <property name="caption">
- <string>wpa_gui</string>
- </property>
- <grid>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
- <property name="name">
- <cstring>textLabel16</cstring>
- </property>
- <property name="text">
- <string>Adapter:</string>
- </property>
- </widget>
- <widget class="QComboBox" row="0" column="2" rowspan="1" colspan="2">
- <property name="name">
- <cstring>adapterSelect</cstring>
- </property>
- </widget>
- <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2">
- <property name="name">
- <cstring>textLabel8</cstring>
- </property>
- <property name="text">
- <string>Network:</string>
- </property>
- </widget>
- <widget class="QComboBox" row="1" column="2" rowspan="1" colspan="2">
- <property name="name">
- <cstring>networkSelect</cstring>
- </property>
- </widget>
- <widget class="QFrame" row="2" column="0" rowspan="1" colspan="4">
- <property name="name">
- <cstring>frame3</cstring>
- </property>
- <property name="frameShape">
- <enum>StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>Raised</enum>
- </property>
- <grid>
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <widget class="QLabel" row="0" column="0">
- <property name="name">
- <cstring>textLabel1</cstring>
- </property>
- <property name="text">
- <string>Status:</string>
- </property>
- </widget>
- <widget class="QLabel" row="1" column="0">
- <property name="name">
- <cstring>textLabel2</cstring>
- </property>
- <property name="text">
- <string>Last message:</string>
- </property>
- </widget>
- <widget class="QLabel" row="2" column="0">
- <property name="name">
- <cstring>textLabel3</cstring>
- </property>
- <property name="text">
- <string>Authentication:</string>
- </property>
- </widget>
- <widget class="QLabel" row="3" column="0">
- <property name="name">
- <cstring>textLabel4</cstring>
- </property>
- <property name="text">
- <string>Encryption:</string>
- </property>
- </widget>
- <widget class="QLabel" row="4" column="0">
- <property name="name">
- <cstring>textLabel5</cstring>
- </property>
- <property name="text">
- <string>SSID:</string>
- </property>
- </widget>
- <widget class="QLabel" row="5" column="0">
- <property name="name">
- <cstring>textLabel6</cstring>
- </property>
- <property name="text">
- <string>BSSID:</string>
- </property>
- </widget>
- <widget class="QLabel" row="6" column="0">
- <property name="name">
- <cstring>textLabel7</cstring>
- </property>
- <property name="text">
- <string>IP address:</string>
- </property>
- </widget>
- <widget class="QLabel" row="0" column="1">
- <property name="name">
- <cstring>textStatus</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="1" column="1" rowspan="1" colspan="3">
- <property name="name">
- <cstring>textLastMessage</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="2" column="1">
- <property name="name">
- <cstring>textAuthentication</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="3" column="1">
- <property name="name">
- <cstring>textEncryption</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="4" column="1">
- <property name="name">
- <cstring>textSsid</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="5" column="1">
- <property name="name">
- <cstring>textBssid</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- <widget class="QLabel" row="6" column="1">
- <property name="name">
- <cstring>textIpAddress</cstring>
- </property>
- <property name="text">
- <string></string>
- </property>
- </widget>
- </grid>
- </widget>
- <spacer row="3" column="0">
- <property name="name">
- <cstring>spacer7</cstring>
- </property>
- <property name="orientation">
- <enum>Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>Expanding</enum>
- </property>
- <property name="sizeHint">
- <size>
- <width>16</width>
- <height>16</height>
- </size>
- </property>
- </spacer>
- <widget class="QPushButton" row="3" column="1">
- <property name="name">
- <cstring>connectButton</cstring>
- </property>
- <property name="text">
- <string>Connect</string>
- </property>
- </widget>
- <widget class="QPushButton" row="3" column="2">
- <property name="name">
- <cstring>disconnectButton</cstring>
- </property>
- <property name="text">
- <string>Disconnect</string>
- </property>
- </widget>
- <widget class="QPushButton" row="3" column="3">
- <property name="name">
- <cstring>scanButton</cstring>
- </property>
- <property name="text">
- <string>Scan</string>
- </property>
- </widget>
- </grid>
-</widget>
-<menubar>
- <property name="name">
- <cstring>MenuBar</cstring>
- </property>
- <item text="&amp;File" name="fileMenu">
- <separator/>
- <action name="fileEventHistoryAction"/>
- <action name="fileAdd_NetworkAction"/>
- <action name="fileEdit_networkAction"/>
- <separator/>
- <action name="fileExitAction"/>
- </item>
- <item text="&amp;Help" name="helpMenu">
- <action name="helpContentsAction"/>
- <action name="helpIndexAction"/>
- <separator/>
- <action name="helpAboutAction"/>
- </item>
-</menubar>
-<toolbars>
-</toolbars>
-<actions>
- <action>
- <property name="name">
- <cstring>fileExitAction</cstring>
- </property>
- <property name="text">
- <string>Exit</string>
- </property>
- <property name="menuText">
- <string>E&amp;xit</string>
- </property>
- <property name="accel">
- <string>Ctrl+Q</string>
- </property>
- </action>
- <action>
- <property name="name">
- <cstring>helpContentsAction</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Contents</string>
- </property>
- <property name="menuText">
- <string>&amp;Contents...</string>
- </property>
- <property name="accel">
- <string></string>
- </property>
- </action>
- <action>
- <property name="name">
- <cstring>helpIndexAction</cstring>
- </property>
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Index</string>
- </property>
- <property name="menuText">
- <string>&amp;Index...</string>
- </property>
- <property name="accel">
- <string></string>
- </property>
- </action>
- <action>
- <property name="name">
- <cstring>helpAboutAction</cstring>
- </property>
- <property name="text">
- <string>About</string>
- </property>
- <property name="menuText">
- <string>&amp;About</string>
- </property>
- <property name="accel">
- <string></string>
- </property>
- </action>
- <action>
- <property name="name">
- <cstring>fileEventHistoryAction</cstring>
- </property>
- <property name="text">
- <string>Event History</string>
- </property>
- <property name="menuText">
- <string>Event &amp;History</string>
- </property>
- </action>
- <action>
- <property name="name">
- <cstring>fileAdd_NetworkAction</cstring>
- </property>
- <property name="text">
- <string>Add Network</string>
- </property>
- <property name="menuText">
- <string>&amp;Add Network</string>
- </property>
- </action>
- <action>
- <property name="name">
- <cstring>fileEdit_networkAction</cstring>
- </property>
- <property name="text">
- <string>Edit Network</string>
- </property>
- <property name="menuText">
- <string>&amp;Edit Network</string>
- </property>
- </action>
-</actions>
-<connections>
- <connection>
- <sender>helpIndexAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>helpIndex()</slot>
- </connection>
- <connection>
- <sender>helpContentsAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>helpContents()</slot>
- </connection>
- <connection>
- <sender>helpAboutAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>helpAbout()</slot>
- </connection>
- <connection>
- <sender>fileExitAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>close()</slot>
- </connection>
- <connection>
- <sender>disconnectButton</sender>
- <signal>clicked()</signal>
- <receiver>WpaGui</receiver>
- <slot>disconnect()</slot>
- </connection>
- <connection>
- <sender>scanButton</sender>
- <signal>clicked()</signal>
- <receiver>WpaGui</receiver>
- <slot>scan()</slot>
- </connection>
- <connection>
- <sender>connectButton</sender>
- <signal>clicked()</signal>
- <receiver>WpaGui</receiver>
- <slot>connectB()</slot>
- </connection>
- <connection>
- <sender>fileEventHistoryAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>eventHistory()</slot>
- </connection>
- <connection>
- <sender>networkSelect</sender>
- <signal>activated(const QString&amp;)</signal>
- <receiver>WpaGui</receiver>
- <slot>selectNetwork(const QString&amp;)</slot>
- </connection>
- <connection>
- <sender>fileEdit_networkAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>editNetwork()</slot>
- </connection>
- <connection>
- <sender>fileAdd_NetworkAction</sender>
- <signal>activated()</signal>
- <receiver>WpaGui</receiver>
- <slot>addNetwork()</slot>
- </connection>
- <connection>
- <sender>adapterSelect</sender>
- <signal>activated(const QString&amp;)</signal>
- <receiver>WpaGui</receiver>
- <slot>selectAdapter(const QString&amp;)</slot>
- </connection>
-</connections>
-<includes>
- <include location="global" impldecl="in declaration">qtimer.h</include>
- <include location="global" impldecl="in declaration">qsocketnotifier.h</include>
- <include location="local" impldecl="in declaration">wpamsg.h</include>
- <include location="local" impldecl="in declaration">eventhistory.h</include>
- <include location="local" impldecl="in declaration">scanresults.h</include>
- <include location="local" impldecl="in implementation">common/wpa_ctrl.h</include>
- <include location="global" impldecl="in implementation">dirent.h</include>
- <include location="global" impldecl="in implementation">qmessagebox.h</include>
- <include location="global" impldecl="in implementation">qapplication.h</include>
- <include location="local" impldecl="in implementation">userdatarequest.h</include>
- <include location="local" impldecl="in implementation">networkconfig.h</include>
- <include location="local" impldecl="in implementation">wpagui.ui.h</include>
-</includes>
-<forwards>
- <forward>class UserDataRequest;</forward>
-</forwards>
-<variables>
- <variable access="private">ScanResults *scanres;</variable>
- <variable access="private">bool networkMayHaveChanged;</variable>
- <variable access="private">char *ctrl_iface;</variable>
- <variable access="private">EventHistory *eh;</variable>
- <variable access="private">struct wpa_ctrl *ctrl_conn;</variable>
- <variable access="private">QSocketNotifier *msgNotifier;</variable>
- <variable access="private">QTimer *timer;</variable>
- <variable access="private">int pingsToStatusUpdate;</variable>
- <variable access="private">WpaMsgList msgs;</variable>
- <variable access="private">char *ctrl_iface_dir;</variable>
- <variable access="private">struct wpa_ctrl *monitor_conn;</variable>
- <variable access="private">UserDataRequest *udr;</variable>
-</variables>
-<slots>
- <slot>parse_argv()</slot>
- <slot>updateStatus()</slot>
- <slot>updateNetworks()</slot>
- <slot>helpIndex()</slot>
- <slot>helpContents()</slot>
- <slot>helpAbout()</slot>
- <slot>disconnect()</slot>
- <slot>scan()</slot>
- <slot>eventHistory()</slot>
- <slot>ping()</slot>
- <slot>processMsg( char * msg )</slot>
- <slot>processCtrlReq( const char * req )</slot>
- <slot>receiveMsgs()</slot>
- <slot>connectB()</slot>
- <slot>selectNetwork( const QString &amp; sel )</slot>
- <slot>editNetwork()</slot>
- <slot>addNetwork()</slot>
- <slot>selectAdapter( const QString &amp; sel )</slot>
-</slots>
-<functions>
- <function access="private" specifier="non virtual">init()</function>
- <function access="private" specifier="non virtual">destroy()</function>
- <function access="private" specifier="non virtual" returnType="int">openCtrlConnection( const char * ifname )</function>
- <function returnType="int">ctrlRequest( const char * cmd, char * buf, size_t * buflen )</function>
- <function>triggerUpdate()</function>
-</functions>
-<pixmapinproject/>
-<layoutdefaults spacing="6" margin="11"/>
-</UI>
diff --git a/wpa_supplicant/wpa_gui/wpagui.ui.h b/wpa_supplicant/wpa_gui/wpagui.ui.h
deleted file mode 100644
index 678ff1b..0000000
--- a/wpa_supplicant/wpa_gui/wpagui.ui.h
+++ /dev/null
@@ -1,730 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-
-#ifdef __MINGW32__
-/* Need to get getopt() */
-#include <unistd.h>
-#endif
-
-#include <stdlib.h>
-
-void WpaGui::init()
-{
- eh = NULL;
- scanres = NULL;
- udr = NULL;
- ctrl_iface = NULL;
- ctrl_conn = NULL;
- monitor_conn = NULL;
- msgNotifier = NULL;
- ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
-
- parse_argv();
-
- textStatus->setText("connecting to wpa_supplicant");
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), SLOT(ping()));
- timer->start(1000, FALSE);
-
- if (openCtrlConnection(ctrl_iface) < 0) {
- printf("Failed to open control connection to wpa_supplicant.\n");
- }
-
- updateStatus();
- networkMayHaveChanged = true;
- updateNetworks();
-}
-
-
-void WpaGui::destroy()
-{
- delete msgNotifier;
-
- if (monitor_conn) {
- wpa_ctrl_detach(monitor_conn);
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
- if (ctrl_conn) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (eh) {
- eh->close();
- delete eh;
- eh = NULL;
- }
-
- if (scanres) {
- scanres->close();
- delete scanres;
- scanres = NULL;
- }
-
- if (udr) {
- udr->close();
- delete udr;
- udr = NULL;
- }
-
- free(ctrl_iface);
- ctrl_iface = NULL;
-
- free(ctrl_iface_dir);
- ctrl_iface_dir = NULL;
-}
-
-
-void WpaGui::parse_argv()
-{
- int c;
- for (;;) {
- c = getopt(qApp->argc(), qApp->argv(), "i:p:");
- if (c < 0)
- break;
- switch (c) {
- case 'i':
- free(ctrl_iface);
- ctrl_iface = strdup(optarg);
- break;
- case 'p':
- free(ctrl_iface_dir);
- ctrl_iface_dir = strdup(optarg);
- break;
- }
- }
-}
-
-
-int WpaGui::openCtrlConnection(const char *ifname)
-{
- char *cfile;
- int flen;
- char buf[2048], *pos, *pos2;
- size_t len;
-
- if (ifname) {
- if (ifname != ctrl_iface) {
- free(ctrl_iface);
- ctrl_iface = strdup(ifname);
- }
- } else {
-#ifdef CONFIG_CTRL_IFACE_UDP
- free(ctrl_iface);
- ctrl_iface = strdup("udp");
-#endif /* CONFIG_CTRL_IFACE_UDP */
-#ifdef CONFIG_CTRL_IFACE_UNIX
- struct dirent *dent;
- DIR *dir = opendir(ctrl_iface_dir);
- free(ctrl_iface);
- ctrl_iface = NULL;
- if (dir) {
- while ((dent = readdir(dir))) {
-#ifdef _DIRENT_HAVE_D_TYPE
- /* Skip the file if it is not a socket.
- * Also accept DT_UNKNOWN (0) in case
- * the C library or underlying file
- * system does not support d_type. */
- if (dent->d_type != DT_SOCK &&
- dent->d_type != DT_UNKNOWN)
- continue;
-#endif /* _DIRENT_HAVE_D_TYPE */
-
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- printf("Selected interface '%s'\n", dent->d_name);
- ctrl_iface = strdup(dent->d_name);
- break;
- }
- closedir(dir);
- }
-#endif /* CONFIG_CTRL_IFACE_UNIX */
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- struct wpa_ctrl *ctrl;
- int ret;
-
- free(ctrl_iface);
- ctrl_iface = NULL;
-
- ctrl = wpa_ctrl_open(NULL);
- if (ctrl) {
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
- if (ret >= 0) {
- buf[len] = '\0';
- pos = strchr(buf, '\n');
- if (pos)
- *pos = '\0';
- ctrl_iface = strdup(buf);
- }
- wpa_ctrl_close(ctrl);
- }
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- }
-
- if (ctrl_iface == NULL)
- return -1;
-
-#ifdef CONFIG_CTRL_IFACE_UNIX
- flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
- cfile = (char *) malloc(flen);
- if (cfile == NULL)
- return -1;
- snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
-#else /* CONFIG_CTRL_IFACE_UNIX */
- flen = strlen(ctrl_iface) + 1;
- cfile = (char *) malloc(flen);
- if (cfile == NULL)
- return -1;
- snprintf(cfile, flen, "%s", ctrl_iface);
-#endif /* CONFIG_CTRL_IFACE_UNIX */
-
- if (ctrl_conn) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (monitor_conn) {
- delete msgNotifier;
- msgNotifier = NULL;
- wpa_ctrl_detach(monitor_conn);
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
-
- printf("Trying to connect to '%s'\n", cfile);
- ctrl_conn = wpa_ctrl_open(cfile);
- if (ctrl_conn == NULL) {
- free(cfile);
- return -1;
- }
- monitor_conn = wpa_ctrl_open(cfile);
- free(cfile);
- if (monitor_conn == NULL) {
- wpa_ctrl_close(ctrl_conn);
- return -1;
- }
- if (wpa_ctrl_attach(monitor_conn)) {
- printf("Failed to attach to wpa_supplicant\n");
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- return -1;
- }
-
-#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
- msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
- QSocketNotifier::Read, this);
- connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
-#endif
-
- adapterSelect->clear();
- adapterSelect->insertItem(ctrl_iface);
- adapterSelect->setCurrentItem(0);
-
- len = sizeof(buf) - 1;
- if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) {
- buf[len] = '\0';
- pos = buf;
- while (*pos) {
- pos2 = strchr(pos, '\n');
- if (pos2)
- *pos2 = '\0';
- if (strcmp(pos, ctrl_iface) != 0)
- adapterSelect->insertItem(pos);
- if (pos2)
- pos = pos2 + 1;
- else
- break;
- }
- }
-
- return 0;
-}
-
-
-static void wpa_gui_msg_cb(char *msg, size_t)
-{
- /* This should not happen anymore since two control connections are used. */
- printf("missed message: %s\n", msg);
-}
-
-
-int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
-{
- int ret;
-
- if (ctrl_conn == NULL)
- return -3;
- ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
- wpa_gui_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- }
-
- return ret;
-}
-
-
-void WpaGui::updateStatus()
-{
- char buf[2048], *start, *end, *pos;
- size_t len;
-
- pingsToStatusUpdate = 10;
-
- len = sizeof(buf) - 1;
- if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
- textStatus->setText("Could not get status from wpa_supplicant");
- textAuthentication->clear();
- textEncryption->clear();
- textSsid->clear();
- textBssid->clear();
- textIpAddress->clear();
- return;
- }
-
- buf[len] = '\0';
-
- bool auth_updated = false, ssid_updated = false;
- bool bssid_updated = false, ipaddr_updated = false;
- bool status_updated = false;
- char *pairwise_cipher = NULL, *group_cipher = NULL;
-
- start = buf;
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- pos = strchr(start, '=');
- if (pos) {
- *pos++ = '\0';
- if (strcmp(start, "bssid") == 0) {
- bssid_updated = true;
- textBssid->setText(pos);
- } else if (strcmp(start, "ssid") == 0) {
- ssid_updated = true;
- textSsid->setText(pos);
- } else if (strcmp(start, "ip_address") == 0) {
- ipaddr_updated = true;
- textIpAddress->setText(pos);
- } else if (strcmp(start, "wpa_state") == 0) {
- status_updated = true;
- textStatus->setText(pos);
- } else if (strcmp(start, "key_mgmt") == 0) {
- auth_updated = true;
- textAuthentication->setText(pos);
- /* TODO: could add EAP status to this */
- } else if (strcmp(start, "pairwise_cipher") == 0) {
- pairwise_cipher = pos;
- } else if (strcmp(start, "group_cipher") == 0) {
- group_cipher = pos;
- }
- }
-
- if (last)
- break;
- start = end + 1;
- }
-
- if (pairwise_cipher || group_cipher) {
- QString encr;
- if (pairwise_cipher && group_cipher &&
- strcmp(pairwise_cipher, group_cipher) != 0) {
- encr.append(pairwise_cipher);
- encr.append(" + ");
- encr.append(group_cipher);
- } else if (pairwise_cipher) {
- encr.append(pairwise_cipher);
- } else {
- encr.append(group_cipher);
- encr.append(" [group key only]");
- }
- textEncryption->setText(encr);
- } else
- textEncryption->clear();
-
- if (!status_updated)
- textStatus->clear();
- if (!auth_updated)
- textAuthentication->clear();
- if (!ssid_updated)
- textSsid->clear();
- if (!bssid_updated)
- textBssid->clear();
- if (!ipaddr_updated)
- textIpAddress->clear();
-}
-
-
-void WpaGui::updateNetworks()
-{
- char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
- size_t len;
- int first_active = -1;
- bool selected = false;
-
- if (!networkMayHaveChanged)
- return;
-
- networkSelect->clear();
-
- if (ctrl_conn == NULL)
- return;
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
- return;
-
- buf[len] = '\0';
- start = strchr(buf, '\n');
- if (start == NULL)
- return;
- start++;
-
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- id = start;
- ssid = strchr(id, '\t');
- if (ssid == NULL)
- break;
- *ssid++ = '\0';
- bssid = strchr(ssid, '\t');
- if (bssid == NULL)
- break;
- *bssid++ = '\0';
- flags = strchr(bssid, '\t');
- if (flags == NULL)
- break;
- *flags++ = '\0';
-
- QString network(id);
- network.append(": ");
- network.append(ssid);
- networkSelect->insertItem(network);
-
- if (strstr(flags, "[CURRENT]")) {
- networkSelect->setCurrentItem(networkSelect->count() - 1);
- selected = true;
- } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
- first_active = networkSelect->count() - 1;
-
- if (last)
- break;
- start = end + 1;
- }
-
- if (!selected && first_active >= 0)
- networkSelect->setCurrentItem(first_active);
-
- networkMayHaveChanged = false;
-}
-
-
-void WpaGui::helpIndex()
-{
- printf("helpIndex\n");
-}
-
-
-void WpaGui::helpContents()
-{
- printf("helpContents\n");
-}
-
-
-void WpaGui::helpAbout()
-{
- QMessageBox::about(this, "wpa_gui for wpa_supplicant",
- "Copyright (c) 2003-2008,\n"
- "Jouni Malinen <j@w1.fi>\n"
- "and contributors.\n"
- "\n"
- "This program is free software. You can\n"
- "distribute it and/or modify it under the terms of\n"
- "the GNU General Public License version 2.\n"
- "\n"
- "Alternatively, this software may be distributed\n"
- "under the terms of the BSD license.\n"
- "\n"
- "This product includes software developed\n"
- "by the OpenSSL Project for use in the\n"
- "OpenSSL Toolkit (http://www.openssl.org/)\n");
-}
-
-
-void WpaGui::disconnect()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
- ctrlRequest("DISCONNECT", reply, &reply_len);
-}
-
-
-void WpaGui::scan()
-{
- if (scanres) {
- scanres->close();
- delete scanres;
- }
-
- scanres = new ScanResults();
- if (scanres == NULL)
- return;
- scanres->setWpaGui(this);
- scanres->show();
- scanres->exec();
-}
-
-
-void WpaGui::eventHistory()
-{
- if (eh) {
- eh->close();
- delete eh;
- }
-
- eh = new EventHistory();
- if (eh == NULL)
- return;
- eh->addEvents(msgs);
- eh->show();
- eh->exec();
-}
-
-
-void WpaGui::ping()
-{
- char buf[10];
- size_t len;
-
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- /*
- * QSocketNotifier cannot be used with Windows named pipes, so use a timer
- * to check for received messages for now. This could be optimized be doing
- * something specific to named pipes or Windows events, but it is not clear
- * what would be the best way of doing that in Qt.
- */
- receiveMsgs();
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
-
- if (scanres && !scanres->isVisible()) {
- delete scanres;
- scanres = NULL;
- }
-
- if (eh && !eh->isVisible()) {
- delete eh;
- eh = NULL;
- }
-
- if (udr && !udr->isVisible()) {
- delete udr;
- udr = NULL;
- }
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("PING", buf, &len) < 0) {
- printf("PING failed - trying to reconnect\n");
- if (openCtrlConnection(ctrl_iface) >= 0) {
- printf("Reconnected successfully\n");
- pingsToStatusUpdate = 0;
- }
- }
-
- pingsToStatusUpdate--;
- if (pingsToStatusUpdate <= 0) {
- updateStatus();
- updateNetworks();
- }
-}
-
-
-static int str_match(const char *a, const char *b)
-{
- return strncmp(a, b, strlen(b)) == 0;
-}
-
-
-void WpaGui::processMsg(char *msg)
-{
- char *pos = msg, *pos2;
- int priority = 2;
-
- if (*pos == '<') {
- /* skip priority */
- pos++;
- priority = atoi(pos);
- pos = strchr(pos, '>');
- if (pos)
- pos++;
- else
- pos = msg;
- }
-
- WpaMsg wm(pos, priority);
- if (eh)
- eh->addEvent(wm);
- msgs.append(wm);
- while (msgs.count() > 100)
- msgs.pop_front();
-
- /* Update last message with truncated version of the event */
- if (strncmp(pos, "CTRL-", 5) == 0) {
- pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
- if (pos2)
- pos2++;
- else
- pos2 = pos;
- } else
- pos2 = pos;
- QString lastmsg = pos2;
- lastmsg.truncate(40);
- textLastMessage->setText(lastmsg);
-
- pingsToStatusUpdate = 0;
- networkMayHaveChanged = true;
-
- if (str_match(pos, WPA_CTRL_REQ))
- processCtrlReq(pos + strlen(WPA_CTRL_REQ));
-}
-
-
-void WpaGui::processCtrlReq(const char *req)
-{
- if (udr) {
- udr->close();
- delete udr;
- }
- udr = new UserDataRequest();
- if (udr == NULL)
- return;
- if (udr->setParams(this, req) < 0) {
- delete udr;
- udr = NULL;
- return;
- }
- udr->show();
- udr->exec();
-}
-
-
-void WpaGui::receiveMsgs()
-{
- char buf[256];
- size_t len;
-
- while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
- len = sizeof(buf) - 1;
- if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
- buf[len] = '\0';
- processMsg(buf);
- }
- }
-}
-
-
-void WpaGui::connectB()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
- ctrlRequest("REASSOCIATE", reply, &reply_len);
-}
-
-
-void WpaGui::selectNetwork( const QString &sel )
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- int pos = cmd.find(':');
- if (pos < 0) {
- printf("Invalid selectNetwork '%s'\n", cmd.ascii());
- return;
- }
- cmd.truncate(pos);
- cmd.prepend("SELECT_NETWORK ");
- ctrlRequest(cmd.ascii(), reply, &reply_len);
-}
-
-
-void WpaGui::editNetwork()
-{
- QString sel(networkSelect->currentText());
- int pos = sel.find(':');
- if (pos < 0) {
- printf("Invalid selectNetwork '%s'\n", sel.ascii());
- return;
- }
- sel.truncate(pos);
-
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(this);
-
- nc->paramsFromConfig(sel.toInt());
- nc->show();
- nc->exec();
-}
-
-
-void WpaGui::triggerUpdate()
-{
- updateStatus();
- networkMayHaveChanged = true;
- updateNetworks();
-}
-
-
-void WpaGui::addNetwork()
-{
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(this);
- nc->newNetwork();
- nc->show();
- nc->exec();
-}
-
-
-void WpaGui::selectAdapter( const QString & sel )
-{
- if (openCtrlConnection(sel.ascii()) < 0)
- printf("Failed to open control connection to wpa_supplicant.\n");
- updateStatus();
- updateNetworks();
-}
diff --git a/wpa_supplicant/wpa_gui/wpamsg.h b/wpa_supplicant/wpa_gui/wpamsg.h
deleted file mode 100644
index f3fce06..0000000
--- a/wpa_supplicant/wpa_gui/wpamsg.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef WPAMSG_H
-#define WPAMSG_H
-
-class WpaMsg;
-
-#if QT_VERSION >= 0x040000
-#include <QDateTime>
-#include <QLinkedList>
-typedef QLinkedList<WpaMsg> WpaMsgList;
-#else
-#include <qdatetime.h>
-typedef QValueList<WpaMsg> WpaMsgList;
-#endif
-
-class WpaMsg {
-public:
- WpaMsg() {}
- WpaMsg(const QString &_msg, int _priority = 2)
- : msg(_msg), priority(_priority)
- {
- timestamp = QDateTime::currentDateTime();
- }
-
- QString getMsg() const { return msg; }
- int getPriority() const { return priority; }
- QDateTime getTimestamp() const { return timestamp; }
-
-private:
- QString msg;
- int priority;
- QDateTime timestamp;
-};
-
-#endif /* WPAMSG_H */
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
index d2a991b..c8854da 100644
--- a/wpa_supplicant/wpa_priv.c
+++ b/wpa_supplicant/wpa_priv.c
@@ -825,7 +825,7 @@ static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface,
}
-void wpa_supplicant_event(void *ctx, wpa_event_type event,
+void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
struct wpa_priv_interface *iface = ctx;
@@ -915,7 +915,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
}
-static void wpa_priv_terminate(int sig, void *eloop_ctx, void *signal_ctx)
+static void wpa_priv_terminate(int sig, void *signal_ctx)
{
wpa_printf(MSG_DEBUG, "wpa_priv termination requested");
eloop_terminate();
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index a1e5456..f626e2e 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -20,6 +20,7 @@
#include "common.h"
#include "crypto/random.h"
+#include "crypto/sha1.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
#include "eap_server/eap_methods.h"
@@ -35,7 +36,6 @@
#include "rsn_supp/preauth.h"
#include "rsn_supp/pmksa_cache.h"
#include "common/wpa_ctrl.h"
-#include "mlme.h"
#include "common/ieee802_11_defs.h"
#include "p2p/p2p.h"
#include "blacklist.h"
@@ -43,12 +43,14 @@
#include "wps_supplicant.h"
#include "ibss_rsn.h"
#include "sme.h"
+#include "gas_query.h"
#include "ap.h"
#include "p2p_supplicant.h"
#include "notify.h"
#include "bgscan.h"
#include "bss.h"
#include "scan.h"
+#include "offchannel.h"
const char *wpa_supplicant_version =
"wpa_supplicant v" VERSION_STR "\n"
@@ -368,6 +370,22 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
}
+static void free_hw_features(struct wpa_supplicant *wpa_s)
+{
+ int i;
+ if (wpa_s->hw.modes == NULL)
+ return;
+
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
+ os_free(wpa_s->hw.modes[i].channels);
+ os_free(wpa_s->hw.modes[i].rates);
+ }
+
+ os_free(wpa_s->hw.modes);
+ wpa_s->hw.modes = NULL;
+}
+
+
static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
{
bgscan_deinit(wpa_s);
@@ -410,8 +428,11 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
wpa_supplicant_cancel_scan(wpa_s);
wpa_supplicant_cancel_auth_timeout(wpa_s);
-
- ieee80211_sta_deinit(wpa_s);
+ eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
+#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
+ eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
+ wpa_s, NULL);
+#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
wpas_wps_deinit(wpa_s);
@@ -433,8 +454,19 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
wpas_p2p_deinit(wpa_s);
#endif /* CONFIG_P2P */
+#ifdef CONFIG_OFFCHANNEL
+ offchannel_deinit(wpa_s);
+#endif /* CONFIG_OFFCHANNEL */
+
+ wpa_supplicant_cancel_sched_scan(wpa_s);
+
os_free(wpa_s->next_scan_freqs);
wpa_s->next_scan_freqs = NULL;
+
+ gas_query_deinit(wpa_s->gas);
+ wpa_s->gas = NULL;
+
+ free_hw_features(wpa_s);
}
@@ -521,6 +553,8 @@ const char * wpa_supplicant_state_txt(enum wpa_states state)
static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
{
+ if (wpas_driver_bss_selection(wpa_s))
+ return;
if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
return;
@@ -678,7 +712,6 @@ void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
{
struct wpa_config *conf;
- struct wpa_ssid *old_ssid;
int reconf_ctrl;
int old_ap_scan;
@@ -703,10 +736,10 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
}
eapol_sm_invalidate_cached_session(wpa_s->eapol);
- old_ssid = wpa_s->current_ssid;
- wpa_s->current_ssid = NULL;
- if (old_ssid != wpa_s->current_ssid)
- wpas_notify_network_changed(wpa_s);
+ if (wpa_s->current_ssid) {
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_DEAUTH_LEAVING);
+ }
/*
* TODO: should notify EAPOL SM about changes in opensc_engine_path,
@@ -721,6 +754,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
}
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
wpa_sm_set_config(wpa_s->wpa, NULL);
+ wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
rsn_preauth_deinit(wpa_s->wpa);
@@ -929,6 +963,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_IEEE80211W */
+ wpa_s->wpa_proto = proto;
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
!!(ssid->proto & WPA_PROTO_RSN));
@@ -1039,10 +1074,20 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
return -1;
}
- if (ssid->key_mgmt &
- (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_PSK_SHA256))
+ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
- else
+#ifndef CONFIG_NO_PBKDF2
+ if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
+ ssid->passphrase) {
+ u8 psk[PMK_LEN];
+ pbkdf2_sha1(ssid->passphrase, (char *) bss->ssid,
+ bss->ssid_len, 4096, psk, PMK_LEN);
+ wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
+ psk, PMK_LEN);
+ wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
+ }
+#endif /* CONFIG_NO_PBKDF2 */
+ } else
wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
return 0;
@@ -1070,6 +1115,9 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
struct wpa_driver_capa capa;
int assoc_failed = 0;
struct wpa_ssid *old_ssid;
+#ifdef ANDROID_P2P
+ int freq = 0;
+#endif
#ifdef CONFIG_IBSS_RSN
ibss_rsn_deinit(wpa_s->ibss_rsn);
@@ -1107,7 +1155,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
os_memset(&params, 0, sizeof(params));
wpa_s->reassociate = 0;
- if (bss) {
+ if (bss && !wpas_driver_bss_selection(wpa_s)) {
#ifdef CONFIG_IEEE80211R
const u8 *ie, *md = NULL;
#endif /* CONFIG_IEEE80211R */
@@ -1145,6 +1193,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
}
+ wpa_supplicant_cancel_sched_scan(wpa_s);
wpa_supplicant_cancel_scan(wpa_s);
/* Starting new association, so clear the possibly used WPA IE from the
@@ -1170,11 +1219,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
- (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
- WPA_KEY_MGMT_FT_IEEE8021X |
- WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_IEEE8021X_SHA256 |
- WPA_KEY_MGMT_PSK_SHA256))) {
+ wpa_key_mgmt_wpa(ssid->key_mgmt)) {
int try_opportunistic;
try_opportunistic = ssid->proactive_key_caching &&
(ssid->proto & WPA_PROTO_RSN);
@@ -1189,11 +1234,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
"key management and encryption suites");
return;
}
- } else if (ssid->key_mgmt &
- (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
- WPA_KEY_MGMT_WPA_NONE | WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_PSK_SHA256 |
- WPA_KEY_MGMT_IEEE8021X_SHA256)) {
+ } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
wpa_ie_len = sizeof(wpa_ie);
if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
wpa_ie, &wpa_ie_len)) {
@@ -1217,10 +1258,12 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
params.wps = WPS_MODE_PRIVACY;
else
params.wps = WPS_MODE_OPEN;
+ wpa_s->wpa_proto = 0;
#endif /* CONFIG_WPS */
} else {
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
wpa_ie_len = 0;
+ wpa_s->wpa_proto = 0;
}
#ifdef CONFIG_P2P
@@ -1253,6 +1296,22 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->interworking) {
+ u8 *pos = wpa_ie;
+ if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
+ pos += 2 + pos[1];
+ os_memmove(pos + 6, pos, wpa_ie_len - (pos - wpa_ie));
+ wpa_ie_len += 6;
+ *pos++ = WLAN_EID_EXT_CAPAB;
+ *pos++ = 4;
+ *pos++ = 0x00;
+ *pos++ = 0x00;
+ *pos++ = 0x00;
+ *pos++ = 0x80; /* Bit 31 - Interworking */
+ }
+#endif /* CONFIG_INTERWORKING */
+
wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
use_crypt = 1;
cipher_pairwise = cipher_suite2driver(wpa_s->pairwise_cipher);
@@ -1292,10 +1351,12 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
if (bss) {
- params.bssid = bss->bssid;
params.ssid = bss->ssid;
params.ssid_len = bss->ssid_len;
- params.freq = bss->freq;
+ if (!wpas_driver_bss_selection(wpa_s)) {
+ params.bssid = bss->bssid;
+ params.freq = bss->freq;
+ }
} else {
params.ssid = ssid->ssid;
params.ssid_len = ssid->ssid_len;
@@ -1308,6 +1369,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
params.pairwise_suite = cipher_pairwise;
params.group_suite = cipher_group;
params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
+ params.wpa_proto = wpa_s->wpa_proto;
params.auth_alg = algs;
params.mode = ssid->mode;
for (i = 0; i < NUM_WEP_KEYS; i++) {
@@ -1343,21 +1405,25 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_IEEE80211W */
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
- params.p2p = 1;
-#endif /* CONFIG_P2P */
+ params.p2p = ssid->p2p_group;
if (wpa_s->parent->set_sta_uapsd)
params.uapsd = wpa_s->parent->sta_uapsd;
else
params.uapsd = -1;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- ret = ieee80211_sta_associate(wpa_s, &params);
- else
- ret = wpa_drv_associate(wpa_s, &params);
+#ifdef ANDROID_P2P
+ /* If multichannel concurrency is not supported, check for any frequency
+ * conflict and take appropriate action.
+ */
+ if (((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq) &&
+ !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+ wpa_printf(MSG_ERROR, "Shared interface with conflicting frequency found (%d != %d)"
+ , freq, params.freq);
+ wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq);
+ }
+#endif
+ ret = wpa_drv_associate(wpa_s, &params);
if (ret < 0) {
wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
"failed");
@@ -1463,10 +1529,7 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
u8 *addr = NULL;
if (!is_zero_ether_addr(wpa_s->bssid)) {
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- ieee80211_sta_disassociate(wpa_s, reason_code);
- else
- wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
+ wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
addr = wpa_s->bssid;
}
@@ -1488,11 +1551,7 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
u8 *addr = NULL;
if (!is_zero_ether_addr(wpa_s->bssid)) {
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- ieee80211_sta_deauthenticate(wpa_s, reason_code);
- else
- wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
- reason_code);
+ wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code);
addr = wpa_s->bssid;
}
@@ -1628,6 +1687,14 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
if (was_disabled != other_ssid->disabled)
wpas_notify_network_enabled_changed(wpa_s, other_ssid);
}
+
+ if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
+ /* We are already associated with the selected network */
+ wpa_printf(MSG_DEBUG, "Already associated with the "
+ "selected network - do nothing");
+ return;
+ }
+
wpa_s->connect_without_scan = NULL;
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
@@ -1654,13 +1721,14 @@ int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
return -1;
#ifdef ANDROID
- if ((ap_scan == 2) && ((wpa_s->wpa_state >= WPA_ASSOCIATING) &&
- (wpa_s->wpa_state < WPA_COMPLETED))) {
- wpa_printf(MSG_ERROR, "ap_scan = %d (%d)",wpa_s->conf->ap_scan,
- ap_scan);
+ if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
+ wpa_s->wpa_state >= WPA_ASSOCIATING &&
+ wpa_s->wpa_state < WPA_COMPLETED) {
+ wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
+ "associating", wpa_s->conf->ap_scan, ap_scan);
return 0;
}
-#endif
+#endif /* ANDROID */
old_ap_scan = wpa_s->conf->ap_scan;
wpa_s->conf->ap_scan = ap_scan;
@@ -1774,25 +1842,15 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
u8 bssid[ETH_ALEN];
int wired;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
- if (ieee80211_sta_get_ssid(wpa_s, ssid, &ssid_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
- "MLME");
- return NULL;
- }
- } else {
- res = wpa_drv_get_ssid(wpa_s, ssid);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
- "driver");
- return NULL;
- }
- ssid_len = res;
+ res = wpa_drv_get_ssid(wpa_s, ssid);
+ if (res < 0) {
+ wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
+ "driver");
+ return NULL;
}
+ ssid_len = res;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
- else if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
+ if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
"driver");
return NULL;
@@ -1817,6 +1875,12 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
return entry;
#endif /* CONFIG_WPS */
+
+ if (!entry->disabled && entry->bssid_set &&
+ entry->ssid_len == 0 &&
+ os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
+ return entry;
+
entry = entry->next;
}
@@ -1824,6 +1888,26 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
}
+static int select_driver(struct wpa_supplicant *wpa_s, int i)
+{
+ struct wpa_global *global = wpa_s->global;
+
+ if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
+ global->drv_priv[i] = wpa_drivers[i]->global_init();
+ if (global->drv_priv[i] == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to initialize driver "
+ "'%s'", wpa_drivers[i]->name);
+ return -1;
+ }
+ }
+
+ wpa_s->driver = wpa_drivers[i];
+ wpa_s->global_drv_priv = global->drv_priv[i];
+
+ return 0;
+}
+
+
static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
const char *name)
{
@@ -1842,9 +1926,7 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
if (name == NULL) {
/* default to first driver in the list */
- wpa_s->driver = wpa_drivers[0];
- wpa_s->global_drv_priv = wpa_s->global->drv_priv[0];
- return 0;
+ return select_driver(wpa_s, 0);
}
do {
@@ -1857,12 +1939,8 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
for (i = 0; wpa_drivers[i]; i++) {
if (os_strlen(wpa_drivers[i]->name) == len &&
os_strncmp(driver, wpa_drivers[i]->name, len) ==
- 0) {
- wpa_s->driver = wpa_drivers[i];
- wpa_s->global_drv_priv =
- wpa_s->global->drv_priv[i];
- return 0;
- }
+ 0)
+ return select_driver(wpa_s, i);
}
driver = pos + 1;
@@ -1984,25 +2062,15 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
}
-/**
- * wpa_supplicant_driver_init - Initialize driver interface parameters
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 on success, -1 on failure
- *
- * This function is called to initialize driver interface parameters.
- * wpa_drv_init() must have been called before this function to initialize the
- * driver interface.
- */
-int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
+int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
{
- static int interface_count = 0;
-
if (wpa_s->driver->send_eapol) {
const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
if (addr)
os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
} else if (!(wpa_s->drv_flags &
WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
+ l2_packet_deinit(wpa_s->l2);
wpa_s->l2 = l2_packet_init(wpa_s->ifname,
wpa_drv_get_mac_addr(wpa_s),
ETH_P_EAPOL,
@@ -2022,6 +2090,27 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
MAC2STR(wpa_s->own_addr));
+ wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
+
+ return 0;
+}
+
+
+/**
+ * wpa_supplicant_driver_init - Initialize driver interface parameters
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is called to initialize driver interface parameters.
+ * wpa_drv_init() must have been called before this function to initialize the
+ * driver interface.
+ */
+int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
+{
+ static int interface_count = 0;
+
+ if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
+ return -1;
if (wpa_s->bridge_ifname[0]) {
wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
@@ -2050,7 +2139,10 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
if (wpa_supplicant_enabled_networks(wpa_s->conf)) {
- wpa_supplicant_req_scan(wpa_s, interface_count, 100000);
+ if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
+ 100000))
+ wpa_supplicant_req_scan(wpa_s, interface_count,
+ 100000);
interface_count++;
} else
wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
@@ -2077,6 +2169,7 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void)
wpa_s->scan_interval = 5;
wpa_s->new_connection = 1;
wpa_s->parent = wpa_s;
+ wpa_s->sched_scanning = 0;
return wpa_s;
}
@@ -2234,13 +2327,18 @@ next_driver:
return -1;
}
+ wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
+ &wpa_s->hw.num_modes,
+ &wpa_s->hw.flags);
+
if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
+ wpa_s->drv_capa_known = 1;
wpa_s->drv_flags = capa.flags;
- if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
- if (ieee80211_sta_init(wpa_s))
- return -1;
- }
+ wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
wpa_s->max_scan_ssids = capa.max_scan_ssids;
+ wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
+ wpa_s->sched_scan_supported = capa.sched_scan_supported;
+ wpa_s->max_match_sets = capa.max_match_sets;
wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
wpa_s->max_stations = capa.max_stations;
}
@@ -2261,8 +2359,6 @@ next_driver:
return -1;
}
- wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
-
if (wpas_wps_init(wpa_s))
return -1;
@@ -2284,6 +2380,12 @@ next_driver:
return -1;
}
+ wpa_s->gas = gas_query_init(wpa_s);
+ if (wpa_s->gas == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
+ return -1;
+ }
+
#ifdef CONFIG_P2P
if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
@@ -2517,6 +2619,13 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
if (params == NULL)
return NULL;
+#ifdef CONFIG_DRIVER_NDIS
+ {
+ void driver_ndis_init_ops(void);
+ driver_ndis_init_ops();
+ }
+#endif /* CONFIG_DRIVER_NDIS */
+
#ifndef CONFIG_NO_WPA_MSG
wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
#endif /* CONFIG_NO_WPA_MSG */
@@ -2593,17 +2702,6 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
wpa_supplicant_deinit(global);
return NULL;
}
- for (i = 0; wpa_drivers[i]; i++) {
- if (!wpa_drivers[i]->global_init)
- continue;
- global->drv_priv[i] = wpa_drivers[i]->global_init();
- if (global->drv_priv[i] == NULL) {
- wpa_printf(MSG_ERROR, "Failed to initialize driver "
- "'%s'", wpa_drivers[i]->name);
- wpa_supplicant_deinit(global);
- return NULL;
- }
- }
return global;
}
@@ -2655,6 +2753,7 @@ void wpa_supplicant_deinit(struct wpa_global *global)
if (global == NULL)
return;
+
#ifdef CONFIG_P2P
wpas_p2p_deinit_global(global);
#endif /* CONFIG_P2P */
@@ -2723,23 +2822,6 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
}
-void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
- size_t num_hw_features)
-{
- size_t i;
-
- if (hw_features == NULL)
- return;
-
- for (i = 0; i < num_hw_features; i++) {
- os_free(hw_features[i].channels);
- os_free(hw_features[i].rates);
- }
-
- os_free(hw_features);
-}
-
-
static void add_freq(int *freqs, int *num_freqs, int freq)
{
int i;
@@ -2846,3 +2928,10 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
wpa_supplicant_req_scan(wpa_s, timeout / 1000,
1000 * (timeout % 1000));
}
+
+
+int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
+{
+ return wpa_s->conf->ap_scan == 2 ||
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
+}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 62c111d..8a66a80 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -228,98 +228,11 @@ struct wpa_global {
};
-struct wpa_client_mlme {
-#ifdef CONFIG_CLIENT_MLME
- enum {
- IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
- IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED,
- IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED
- } state;
- u8 prev_bssid[ETH_ALEN];
- u8 ssid[32];
- size_t ssid_len;
- u16 aid;
- u16 ap_capab, capab;
- u8 *extra_ie; /* to be added to the end of AssocReq */
- size_t extra_ie_len;
- u8 *extra_probe_ie; /* to be added to the end of ProbeReq */
- size_t extra_probe_ie_len;
- enum wpa_key_mgmt key_mgmt;
-
- /* The last AssocReq/Resp IEs */
- u8 *assocreq_ies, *assocresp_ies;
- size_t assocreq_ies_len, assocresp_ies_len;
-
- int auth_tries, assoc_tries;
-
- unsigned int ssid_set:1;
- unsigned int bssid_set:1;
- unsigned int prev_bssid_set:1;
- unsigned int authenticated:1;
- unsigned int associated:1;
- unsigned int probereq_poll:1;
- unsigned int use_protection:1;
- unsigned int create_ibss:1;
- unsigned int mixed_cell:1;
- unsigned int wmm_enabled:1;
-
- struct os_time last_probe;
-
- unsigned int auth_algs; /* bitfield of allowed auth algs
- * (WPA_AUTH_ALG_*) */
- int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
- int auth_transaction;
-
- struct os_time ibss_join_req;
- u8 *probe_resp; /* ProbeResp template for IBSS */
- size_t probe_resp_len;
- u32 supp_rates_bits;
-
- int wmm_last_param_set;
-
- int sta_scanning;
- int scan_hw_mode_idx;
- int scan_channel_idx;
- enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
- struct os_time last_scan_completed;
- int scan_oper_channel;
- int scan_oper_freq;
- int scan_oper_phymode;
- u8 scan_ssid[32];
- size_t scan_ssid_len;
- int scan_skip_11b;
- int *scan_freqs;
-
- struct ieee80211_sta_bss *sta_bss_list;
-#define STA_HASH_SIZE 256
-#define STA_HASH(sta) (sta[5])
- struct ieee80211_sta_bss *sta_bss_hash[STA_HASH_SIZE];
-
- int cts_protect_erp_frames;
-
- enum hostapd_hw_mode phymode; /* current mode */
- struct hostapd_hw_modes *modes;
- size_t num_modes;
- unsigned int hw_modes; /* bitfield of allowed hardware modes;
- * (1 << HOSTAPD_MODE_*) */
- int num_curr_rates;
- int *curr_rates;
- int freq; /* The current frequency in MHz */
- int channel; /* The current IEEE 802.11 channel number */
-
-#ifdef CONFIG_IEEE80211R
- u8 current_md[6];
- u8 *ft_ies;
- size_t ft_ies_len;
-#endif /* CONFIG_IEEE80211R */
-
- void (*public_action_cb)(void *ctx, const u8 *buf, size_t len,
- int freq);
- void *public_action_cb_ctx;
-
-#else /* CONFIG_CLIENT_MLME */
- int dummy; /* to keep MSVC happy */
-#endif /* CONFIG_CLIENT_MLME */
+enum offchannel_send_action_result {
+ OFFCHANNEL_SEND_ACTION_SUCCESS /* Frame was send and acknowledged */,
+ OFFCHANNEL_SEND_ACTION_NO_ACK /* Frame was sent, but not acknowledged
+ */,
+ OFFCHANNEL_SEND_ACTION_FAILED /* Frame was not sent due to a failure */
};
/**
@@ -353,7 +266,7 @@ struct wpa_supplicant {
os_time_t last_michael_mic_error;
u8 bssid[ETH_ALEN];
u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this
- * field contains the targer BSSID. */
+ * field contains the target BSSID. */
int reassociate; /* reassociation requested */
int disconnected; /* all connections disabled; i.e., do no reassociate
* before this has been cleared */
@@ -366,6 +279,7 @@ struct wpa_supplicant {
int pairwise_cipher;
int group_cipher;
int key_mgmt;
+ int wpa_proto;
int mgmt_group_cipher;
void *drv_priv; /* private data used by driver_ops */
@@ -379,6 +293,12 @@ struct wpa_supplicant {
*/
#define WILDCARD_SSID_SCAN ((struct wpa_ssid *) 1)
+ struct wpa_ssid *prev_sched_ssid; /* last SSID used in sched scan */
+ int sched_scan_timeout;
+ int sched_scan_interval;
+ int first_sched_scan;
+ int sched_scan_timed_out;
+
void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res);
struct dl_list bss; /* struct wpa_bss::list */
@@ -397,6 +317,7 @@ struct wpa_supplicant {
enum wpa_states wpa_state;
int scanning;
+ int sched_scanning;
int new_connection;
int reassociated_connection;
@@ -416,10 +337,20 @@ struct wpa_supplicant {
int scan_runs; /* number of scan runs since WPS was started */
int *next_scan_freqs;
int scan_interval; /* time in sec between scans to find suitable AP */
+ int normal_scans; /* normal scans run before sched_scan */
- struct wpa_client_mlme mlme;
unsigned int drv_flags;
+
+ /*
+ * A bitmap of supported protocols for probe response offload. See
+ * struct wpa_driver_capa in driver.h
+ */
+ unsigned int probe_resp_offloads;
+
int max_scan_ssids;
+ int max_sched_scan_ssids;
+ int sched_scan_supported;
+ unsigned int max_match_sets;
unsigned int max_remain_on_chan;
unsigned int max_stations;
@@ -458,6 +389,7 @@ struct wpa_supplicant {
u8 prev_bssid[ETH_ALEN];
int prev_bssid_set;
int auth_alg;
+ int proto;
int sa_query_count; /* number of pending SA Query requests;
* 0 = no SA Query in progress */
@@ -476,20 +408,30 @@ struct wpa_supplicant {
void *ap_configured_cb_data;
#endif /* CONFIG_AP */
-#ifdef CONFIG_P2P
- struct p2p_go_neg_results *go_params;
- int create_p2p_iface;
- u8 pending_interface_addr[ETH_ALEN];
- char pending_interface_name[100];
- int pending_interface_type;
- int p2p_group_idx;
unsigned int off_channel_freq;
struct wpabuf *pending_action_tx;
u8 pending_action_src[ETH_ALEN];
u8 pending_action_dst[ETH_ALEN];
u8 pending_action_bssid[ETH_ALEN];
unsigned int pending_action_freq;
+ int pending_action_no_cck;
int pending_action_without_roc;
+ void (*pending_action_tx_status_cb)(struct wpa_supplicant *wpa_s,
+ unsigned int freq, const u8 *dst,
+ const u8 *src, const u8 *bssid,
+ const u8 *data, size_t data_len,
+ enum offchannel_send_action_result
+ result);
+ unsigned int roc_waiting_drv_freq;
+ int action_tx_wait_time;
+
+#ifdef CONFIG_P2P
+ struct p2p_go_neg_results *go_params;
+ int create_p2p_iface;
+ u8 pending_interface_addr[ETH_ALEN];
+ char pending_interface_name[100];
+ int pending_interface_type;
+ int p2p_group_idx;
unsigned int pending_listen_freq;
unsigned int pending_listen_duration;
enum {
@@ -513,8 +455,6 @@ struct wpa_supplicant {
u8 pending_join_dev_addr[ETH_ALEN];
int pending_join_wps_method;
int p2p_join_scan_count;
- unsigned int roc_waiting_drv_freq;
- int action_tx_wait_time;
int force_long_sd;
/*
@@ -544,6 +484,8 @@ struct wpa_supplicant {
P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
P2P_GROUP_REMOVAL_UNAVAILABLE
} removal_reason;
+
+ unsigned int p2p_cb_on_scan_complete:1;
#endif /* CONFIG_P2P */
struct wpa_ssid *bgscan_ssid;
@@ -561,6 +503,23 @@ struct wpa_supplicant {
int best_24_freq;
int best_5_freq;
int best_overall_freq;
+
+ struct gas_query *gas;
+
+#ifdef CONFIG_INTERWORKING
+ unsigned int fetch_anqp_in_progress:1;
+ unsigned int network_select:1;
+ unsigned int auto_select:1;
+#endif /* CONFIG_INTERWORKING */
+ unsigned int drv_capa_known;
+
+ struct {
+ struct hostapd_hw_modes *modes;
+ u16 num_modes;
+ u16 flags;
+ } hw;
+
+ int pno;
};
@@ -570,6 +529,7 @@ int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s);
const char * wpa_supplicant_state_txt(enum wpa_states state);
+int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s);
int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s);
int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, struct wpa_ssid *ssid,
@@ -631,19 +591,16 @@ enum wpa_key_mgmt key_mgmt2driver(int key_mgmt);
enum wpa_cipher cipher_suite2driver(int cipher);
void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
-void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
- size_t num_hw_features);
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
+int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
/* events.c */
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
-#ifdef ANDROID_BRCM_P2P_PATCH
int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
-#else
-void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
-#endif /* ANDROID_BRCM_P2P_PATCH */
- struct wpa_bss *selected,
- struct wpa_ssid *ssid);
+ struct wpa_bss *selected,
+ struct wpa_ssid *ssid);
+void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx);
+void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx);
/* eap_register.c */
int eap_register_methods(void);
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index edb9475..69b0cf8 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -24,7 +24,6 @@
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "rsn_supp/pmksa_cache.h"
-#include "mlme.h"
#include "sme.h"
#include "common/ieee802_11_defs.h"
#include "common/wpa_ctrl.h"
@@ -438,10 +437,6 @@ static void * wpa_supplicant_get_network_ctx(void *wpa_s)
static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
{
struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
- os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
- return 0;
- }
return wpa_drv_get_bssid(wpa_s, bssid);
}
@@ -489,8 +484,6 @@ static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
const u8 *ies, size_t ies_len)
{
struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len);
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
return sme_update_ft_ies(wpa_s, md, ies, ies_len);
return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
@@ -502,9 +495,6 @@ static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
const u8 *ies, size_t ies_len)
{
struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- return ieee80211_sta_send_ft_action(wpa_s, action, target_ap,
- ies, ies_len);
return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len);
}
@@ -515,9 +505,6 @@ static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap)
struct wpa_driver_auth_params params;
struct wpa_bss *bss;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
- return -1;
-
bss = wpa_bss_get_bssid(wpa_s, target_ap);
if (bss == NULL)
return -1;
@@ -538,6 +525,27 @@ static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap)
#ifdef CONFIG_TDLS
+static int wpa_supplicant_tdls_get_capa(void *ctx, int *tdls_supported,
+ int *tdls_ext_setup)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ *tdls_supported = 0;
+ *tdls_ext_setup = 0;
+
+ if (!wpa_s->drv_capa_known)
+ return -1;
+
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)
+ *tdls_supported = 1;
+
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP)
+ *tdls_ext_setup = 1;
+
+ return 0;
+}
+
+
static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
u8 action_code, u8 dialog_token,
u16 status_code, const u8 *buf,
@@ -555,16 +563,102 @@ static int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer)
return wpa_drv_tdls_oper(wpa_s, oper, peer);
}
+
+static int wpa_supplicant_tdls_peer_addset(
+ void *ctx, const u8 *peer, int add, u16 capability,
+ const u8 *supp_rates, size_t supp_rates_len)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct hostapd_sta_add_params params;
+
+ params.addr = peer;
+ params.aid = 1;
+ params.capability = capability;
+ params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
+ params.ht_capabilities = NULL;
+ params.listen_interval = 0;
+ params.supp_rates = supp_rates;
+ params.supp_rates_len = supp_rates_len;
+ params.set = !add;
+
+ return wpa_drv_sta_add(wpa_s, &params);
+}
+
#endif /* CONFIG_TDLS */
+enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
+{
+ if (os_strcmp(field, "IDENTITY") == 0)
+ return WPA_CTRL_REQ_EAP_IDENTITY;
+ else if (os_strcmp(field, "PASSWORD") == 0)
+ return WPA_CTRL_REQ_EAP_PASSWORD;
+ else if (os_strcmp(field, "NEW_PASSWORD") == 0)
+ return WPA_CTRL_REQ_EAP_NEW_PASSWORD;
+ else if (os_strcmp(field, "PIN") == 0)
+ return WPA_CTRL_REQ_EAP_PIN;
+ else if (os_strcmp(field, "OTP") == 0)
+ return WPA_CTRL_REQ_EAP_OTP;
+ else if (os_strcmp(field, "PASSPHRASE") == 0)
+ return WPA_CTRL_REQ_EAP_PASSPHRASE;
+ return WPA_CTRL_REQ_UNKNOWN;
+}
+
+
+const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
+ const char *default_txt,
+ const char **txt)
+{
+ const char *ret = NULL;
+
+ *txt = default_txt;
+
+ switch (field) {
+ case WPA_CTRL_REQ_EAP_IDENTITY:
+ *txt = "Identity";
+ ret = "IDENTITY";
+ break;
+ case WPA_CTRL_REQ_EAP_PASSWORD:
+ *txt = "Password";
+ ret = "PASSWORD";
+ break;
+ case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
+ *txt = "New Password";
+ ret = "NEW_PASSWORD";
+ break;
+ case WPA_CTRL_REQ_EAP_PIN:
+ *txt = "PIN";
+ ret = "PIN";
+ break;
+ case WPA_CTRL_REQ_EAP_OTP:
+ ret = "OTP";
+ break;
+ case WPA_CTRL_REQ_EAP_PASSPHRASE:
+ *txt = "Private key passphrase";
+ ret = "PASSPHRASE";
+ break;
+ default:
+ break;
+ }
+
+ /* txt needs to be something */
+ if (*txt == NULL) {
+ wpa_printf(MSG_WARNING, "No message for request %d", field);
+ ret = NULL;
+ }
+
+ return ret;
+}
+
#ifdef IEEE8021X_EAPOL
#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
-static void wpa_supplicant_eap_param_needed(void *ctx, const char *field,
- const char *txt)
+static void wpa_supplicant_eap_param_needed(void *ctx,
+ enum wpa_ctrl_req_type field,
+ const char *default_txt)
{
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *ssid = wpa_s->current_ssid;
+ const char *field_name, *txt = NULL;
char *buf;
size_t buflen;
int len;
@@ -572,13 +666,23 @@ static void wpa_supplicant_eap_param_needed(void *ctx, const char *field,
if (ssid == NULL)
return;
+ wpas_notify_network_request(wpa_s, ssid, field, default_txt);
+
+ field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,
+ &txt);
+ if (field_name == NULL) {
+ wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed",
+ field);
+ return;
+ }
+
buflen = 100 + os_strlen(txt) + ssid->ssid_len;
buf = os_malloc(buflen);
if (buf == NULL)
return;
len = os_snprintf(buf, buflen,
WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
- field, ssid->id, txt);
+ field_name, ssid->id, txt);
if (len < 0 || (size_t) len >= buflen) {
os_free(buf);
return;
@@ -667,6 +771,16 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
}
+static void wpa_supplicant_set_rekey_offload(void *ctx, const u8 *kek,
+ const u8 *kck,
+ const u8 *replay_ctr)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpa_drv_set_rekey_info(wpa_s, kek, kck, replay_ctr);
+}
+
+
int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
{
#ifndef CONFIG_NO_WPA
@@ -703,9 +817,12 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
ctx->mark_authenticated = wpa_supplicant_mark_authenticated;
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_TDLS
+ ctx->tdls_get_capa = wpa_supplicant_tdls_get_capa;
ctx->send_tdls_mgmt = wpa_supplicant_send_tdls_mgmt;
ctx->tdls_oper = wpa_supplicant_tdls_oper;
+ ctx->tdls_peer_addset = wpa_supplicant_tdls_peer_addset;
#endif /* CONFIG_TDLS */
+ ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
wpa_s->wpa = wpa_sm_init(ctx);
if (wpa_s->wpa == NULL) {
@@ -729,6 +846,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
conf.peerkey_enabled = ssid->peerkey;
conf.allowed_pairwise_cipher = ssid->pairwise_cipher;
#ifdef IEEE8021X_EAPOL
+ conf.proactive_key_caching = ssid->proactive_key_caching;
conf.eap_workaround = ssid->eap_workaround;
conf.eap_conf_ctx = &ssid->eap;
#endif /* IEEE8021X_EAPOL */
diff --git a/wpa_supplicant/wpas_glue.h b/wpa_supplicant/wpas_glue.h
index b571e4d..78c1b3d 100644
--- a/wpa_supplicant/wpas_glue.h
+++ b/wpa_supplicant/wpas_glue.h
@@ -15,9 +15,17 @@
#ifndef WPAS_GLUE_H
#define WPAS_GLUE_H
+enum wpa_ctrl_req_type;
+
int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s);
int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
+const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
+ const char *default_txt,
+ const char **txt);
+
+enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field);
+
#endif /* WPAS_GLUE_H */
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index e3388bd..870aff5 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -88,6 +88,7 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
}
wpa_s->after_wps = 5;
wpa_s->wps_freq = wpa_s->assoc_freq;
+ wpa_s->normal_scans = 0;
wpa_s->reassociate = 1;
wpa_supplicant_req_scan(wpa_s, 0, 0);
return 1;
@@ -127,6 +128,8 @@ static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
if (wpa_drv_get_capa(wpa_s, &capa))
return; /* Unknown what driver supports */
+ if (ssid->ssid == NULL)
+ return;
bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len);
if (bss == NULL) {
wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS "
@@ -192,7 +195,9 @@ static int wpa_supplicant_wps_cred(void *ctx,
struct wpa_ssid *ssid = wpa_s->current_ssid;
u8 key_idx = 0;
u16 auth_type;
+#ifdef CONFIG_WPS_REG_DISABLE_OPEN
int registrar = 0;
+#endif /* CONFIG_WPS_REG_DISABLE_OPEN */
if ((wpa_s->conf->wps_cred_processing == 1 ||
wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
@@ -246,11 +251,13 @@ static int wpa_supplicant_wps_cred(void *ctx,
if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
"on the received credential");
+#ifdef CONFIG_WPS_REG_DISABLE_OPEN
if (ssid->eap.identity &&
ssid->eap.identity_len == WSC_ID_REGISTRAR_LEN &&
os_memcmp(ssid->eap.identity, WSC_ID_REGISTRAR,
WSC_ID_REGISTRAR_LEN) == 0)
registrar = 1;
+#endif /* CONFIG_WPS_REG_DISABLE_OPEN */
os_free(ssid->eap.identity);
ssid->eap.identity = NULL;
ssid->eap.identity_len = 0;
@@ -787,6 +794,10 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
{
struct wpa_ssid *ssid;
+ if (wpa_s->current_ssid)
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+
/* Mark all other networks disabled and trigger reassociation */
ssid = wpa_s->conf->ssid;
while (ssid) {
@@ -808,6 +819,7 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
wpa_s->scan_runs = 0;
+ wpa_s->normal_scans = 0;
wpa_s->wps_success = 0;
wpa_s->blacklist_cleared = 0;
wpa_supplicant_req_scan(wpa_s, 0, 0);
@@ -1114,6 +1126,8 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
{
struct wps_context *wps;
struct wps_registrar_config rcfg;
+ struct hostapd_hw_modes *modes;
+ u16 m;
wps = os_zalloc(sizeof(*wps));
if (wps == NULL)
@@ -1138,6 +1152,7 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
return -1;
}
wps->config_methods = wps_fix_config_methods(wps->config_methods);
+ wps->dev.config_methods = wps->config_methods;
os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
WPS_DEV_TYPE_LEN);
@@ -1146,7 +1161,23 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
- wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */
+ modes = wpa_s->hw.modes;
+ if (modes) {
+ for (m = 0; m < wpa_s->hw.num_modes; m++) {
+ if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
+ modes[m].mode == HOSTAPD_MODE_IEEE80211G)
+ wps->dev.rf_bands |= WPS_RF_24GHZ;
+ else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
+ wps->dev.rf_bands |= WPS_RF_50GHZ;
+ }
+ }
+ if (wps->dev.rf_bands == 0) {
+ /*
+ * Default to claiming support for both bands if the driver
+ * does not provide support for fetching supported bands.
+ */
+ wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ;
+ }
os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
wpas_wps_set_uuid(wpa_s, wps);