Support for sending BTM request frame to upper layer
Framework need to get MBO attributes and WNM mode fields from BTM request frame
Support the feature of BTM request notification
To take this feature, "btm_offload=1" add to wpa_supplicant.conf
Plus, call "MBO CELL_DATA_CAP" private command to advertise cellular capability to AP
Bug: b/154372567
Test: Test with manipulated BTM frames in Hikey960 (Android R-os)
1. Add "btm_offload=1" to "/data/vendor/wifi/wpa/wpa_supplicant.conf"
2. Setup SoftAP and assoc
3. "wl -i [SoftAP if] actframe [STA_MAC_ADDR] 0a07AA010000ff340d02904c07a4d900000000000b00340d02904c0e54d900000000009500dd07506f9a16060100" in SoftAP
the log below is seen in logcat
wpa_supplicant: wlan0: WNM: Send BSS Transition Management Request frame to upper layer
Signed-off-by: Dennis Jeon <dennis.jeon@broadcom.com>
Change-Id: I07137848cef47ee15f750871520119e7181f4c26
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 3a99bb6..09b8a6d 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -68,6 +68,10 @@
L_CFLAGS += -DCONFIG_NO_ROAMING
endif
+ifeq ($(WIFI_PRIV_CMD_UPDATE_MBO_CELL_STATUS), enabled)
+L_CFLAGS += -DENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
+endif
+
# Use Android specific directory for control interface sockets
L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/vendor/wifi/wpa/sockets\"
L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/vendor/wifi/wpa/sockets\"
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 8a8765b..0d5b285 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -4328,6 +4328,7 @@
config->disassoc_imminent_rssi_threshold =
DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD;
config->oce = DEFAULT_OCE_SUPPORT;
+ config->btm_offload = DEFAULT_BTM_OFFLOAD;
#endif /* CONFIG_MBO */
if (ctrl_interface)
@@ -5111,6 +5112,7 @@
MBO_CELL_CAPA_NOT_SUPPORTED), 0 },
{ INT_RANGE(disassoc_imminent_rssi_threshold, -120, 0), 0 },
{ INT_RANGE(oce, 0, 3), 0 },
+ { INT_RANGE(btm_offload, 0, 1), CFG_CHANGED_DISABLE_BTM_NOTIFY },
#endif /* CONFIG_MBO */
{ INT(gas_address3), 0 },
{ INT_RANGE(ftm_responder, 0, 1), 0 },
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 0b9e3db..868a8b3 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -45,6 +45,7 @@
#define DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD -75
#define DEFAULT_OCE_SUPPORT OCE_STA
#define DEFAULT_EXTENDED_KEY_ID 0
+#define DEFAULT_BTM_OFFLOAD 0
#include "config_ssid.h"
#include "wps/wps.h"
@@ -377,6 +378,7 @@
#define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18)
#define CFG_CHANGED_DISABLE_BTM BIT(19)
#define CFG_CHANGED_BGSCAN BIT(20)
+#define CFG_CHANGED_DISABLE_BTM_NOTIFY BIT(21)
/**
* struct wpa_config - wpa_supplicant configuration data
@@ -1451,6 +1453,14 @@
* - Set BIT(1) to enable OCE in STA-CFON mode
*/
unsigned int oce;
+
+ /**
+ * btm_offload - Set where to perform roaming logic
+ * - Set to 0 to handle fully roaming logic in supplicant
+ * - Set to 1 to skip roaming logic in supplicant for firmware roaming
+ * just parse BTM frame and notify framework
+ */
+ int btm_offload;
#endif /* CONFIG_MBO */
/**
diff --git a/wpa_supplicant/hidl/1.4/sta_iface.cpp b/wpa_supplicant/hidl/1.4/sta_iface.cpp
index 40ec870..1eb36cf 100644
--- a/wpa_supplicant/hidl/1.4/sta_iface.cpp
+++ b/wpa_supplicant/hidl/1.4/sta_iface.cpp
@@ -1543,7 +1543,19 @@
} else {
mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
}
+
+#ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
+ char mbo_cmd[32];
+ char buf[32];
+
+ os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
+ if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
+ wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
+ }
+#else
wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
+#endif
+
return {SupplicantStatusCode::SUCCESS, ""};
#else
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index c706a4e..6996b09 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -1461,6 +1461,22 @@
wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125, url);
}
+#ifdef CONFIG_MBO
+ vendor = get_ie(pos, end - pos, WLAN_EID_VENDOR_SPECIFIC);
+ if (vendor) {
+ wpas_mbo_ie_trans_req(wpa_s, vendor + 2, vendor[1]);
+ if (wpa_s->conf->btm_offload) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "WNM: Notify BSS Transition Management Request frame status");
+ wpa_s->bss_tm_status = WNM_BSS_TM_ACCEPT;
+ wpas_notify_bss_tm_status(wpa_s);
+ /* since it could be referenced in the scan result logic, initialize it */
+ wpa_s->wnm_mbo_trans_reason_present = 0;
+ return;
+ }
+ }
+#endif /* CONFIG_MBO */
+
if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
wpa_msg(wpa_s, MSG_INFO, "WNM: Disassociation Imminent - "
"Disassociation Timer %u", wpa_s->wnm_dissoc_timer);
@@ -1472,12 +1488,6 @@
}
}
-#ifdef CONFIG_MBO
- vendor = get_ie(pos, end - pos, WLAN_EID_VENDOR_SPECIFIC);
- if (vendor)
- wpas_mbo_ie_trans_req(wpa_s, vendor + 2, vendor[1]);
-#endif /* CONFIG_MBO */
-
if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) {
unsigned int valid_ms;
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index c10dd73..2f1e31b 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1646,6 +1646,12 @@
# Set to 1 to disable BSS transition management
#disable_btm=0
+# This value is used to set where to perform roaming logic
+# Set to 0 to handle roaming logic fully in supplicant
+# Set to 1 to skip roaming logic in supplicant and handle it in firmware
+# In supplicant, just parse BTM frame and notify framework
+#btm_offload=0
+
# Enable EDMG capability in STA/AP mode, default value is false
#enable_edmg=1