Merge "Bug fix of 6GHz band channelization"
diff --git a/hostapd/hidl/1.3/hostapd.cpp b/hostapd/hidl/1.3/hostapd.cpp
index aa16e8c..14c04a5 100644
--- a/hostapd/hidl/1.3/hostapd.cpp
+++ b/hostapd/hidl/1.3/hostapd.cpp
@@ -19,6 +19,7 @@
extern "C"
{
+#include "common/wpa_ctrl.h"
#include "utils/eloop.h"
}
@@ -34,6 +35,8 @@
using android::base::StringPrintf;
using android::base::WriteStringToFile;
using android::hardware::wifi::hostapd::V1_2::IHostapd;
+using android::hardware::wifi::hostapd::V1_3::Generation;
+using android::hardware::wifi::hostapd::V1_3::Bandwidth;
std::string WriteHostapdConfig(
const std::string& interface_name, const std::string& config)
@@ -422,6 +425,51 @@
nw_params.V1_0.isHidden ? 1 : 0, encryption_config_as_string.c_str());
}
+Generation getGeneration(hostapd_hw_modes *current_mode)
+{
+ wpa_printf(MSG_DEBUG, "getGeneration hwmode=%d, ht_enabled=%d, vht_enabled=%d",
+ current_mode->mode, current_mode->ht_capab != 0,
+ current_mode->vht_capab != 0);
+ switch (current_mode->mode) {
+ case HOSTAPD_MODE_IEEE80211B:
+ return Generation::WIFI_STANDARD_LEGACY;
+ case HOSTAPD_MODE_IEEE80211G:
+ return current_mode->ht_capab == 0 ?
+ Generation::WIFI_STANDARD_LEGACY : Generation::WIFI_STANDARD_11N;
+ case HOSTAPD_MODE_IEEE80211A:
+ return current_mode->vht_capab == 0 ?
+ Generation::WIFI_STANDARD_11N : Generation::WIFI_STANDARD_11AC;
+ // TODO: b/162484222 miss HOSTAPD_MODE_IEEE80211AX definition.
+ default:
+ return Generation::WIFI_STANDARD_UNKNOWN;
+ }
+}
+
+Bandwidth getBandwidth(struct hostapd_config *iconf)
+{
+ wpa_printf(MSG_DEBUG, "getBandwidth %d, isHT=%d, isHT40=%d",
+ iconf->vht_oper_chwidth, iconf->ieee80211n,
+ iconf->secondary_channel);
+ switch (iconf->vht_oper_chwidth) {
+ case CHANWIDTH_80MHZ:
+ return Bandwidth::WIFI_BANDWIDTH_80;
+ case CHANWIDTH_80P80MHZ:
+ return Bandwidth::WIFI_BANDWIDTH_80P80;
+ break;
+ case CHANWIDTH_160MHZ:
+ return Bandwidth::WIFI_BANDWIDTH_160;
+ break;
+ case CHANWIDTH_USE_HT:
+ if (iconf->ieee80211n) {
+ return iconf->secondary_channel != 0 ?
+ Bandwidth::WIFI_BANDWIDTH_40 : Bandwidth::WIFI_BANDWIDTH_20;
+ }
+ return Bandwidth::WIFI_BANDWIDTH_20_NOHT;
+ default:
+ return Bandwidth::WIFI_BANDWIDTH_INVALID;
+ }
+}
+
// hostapd core functions accept "C" style function pointers, so use global
// functions to pass to the hostapd core function and store the corresponding
// std::function methods to be invoked.
@@ -454,6 +502,22 @@
}
}
+std::function<void(struct hostapd_data*, int level,
+ enum wpa_msg_type type, const char *txt,
+ size_t len)> on_wpa_msg_internal_callback;
+
+void onAsyncWpaEventCb(void *ctx, int level,
+ enum wpa_msg_type type, const char *txt,
+ size_t len)
+{
+ struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+ if (on_wpa_msg_internal_callback) {
+ on_wpa_msg_internal_callback(iface_hapd, level,
+ type, txt, len);
+ }
+}
+
+
} // namespace
namespace android {
@@ -619,12 +683,29 @@
}
};
+ // Register for wpa_event which used to get channel switch event
+ on_wpa_msg_internal_callback =
+ [this](struct hostapd_data* iface_hapd, int level,
+ enum wpa_msg_type type, const char *txt,
+ size_t len) {
+ wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
+ if (os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
+ strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
+ for (const auto &callback : callbacks_) {
+ callback->onApInstanceInfoChanged(
+ iface_hapd->conf->iface, iface_hapd->conf->iface,
+ iface_hapd->iface->freq, getBandwidth(iface_hapd->iconf),
+ getGeneration(iface_hapd->iface->current_mode));
+ }
+ }
+ };
// Setup callback
iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
iface_hapd->setup_complete_cb_ctx = iface_hapd;
iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
iface_hapd->sta_authorized_cb_ctx = iface_hapd;
+ wpa_msg_register_cb(onAsyncWpaEventCb);
if (hostapd_enable_iface(iface_hapd->iface) < 0) {
wpa_printf(
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 812c09a..9fae06d 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -210,7 +210,7 @@
# Frequency list can be provided as range using hyphen ('-') or individual
# frequencies can be specified by comma (',') separated values
# Default: all frequencies allowed in selected hw_mode
-#freqlist=2437,5945,5965
+#freqlist=2437,5955,5975
#freqlist=2437,5985-6105
# Exclude DFS channels from ACS
@@ -822,11 +822,11 @@
#he_rts_threshold=0
# HE operating channel information; see matching vht_* parameters for details.
-# On the 6 GHz band the center freq calculation starts from 5.940 GHz offset.
-# For example idx=3 would result in 5955 MHz center frequency. In addition,
+# On the 6 GHz band the center freq calculation starts from 5.950 GHz offset.
+# For example idx=3 would result in 5965 MHz center frequency. In addition,
# he_oper_chwidth is ignored, and the channel width is derived from the
# configured operating class or center frequency indexes (see
-# IEEE P802.11ax/D4.3 Annex E, Table E-4).
+# IEEE P802.11ax/D6.1 Annex E, Table E-4).
#he_oper_chwidth
#he_oper_centr_freq_seg0_idx
#he_oper_centr_freq_seg1_idx
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 71baf9b..6859787 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -939,9 +939,9 @@
return HOSTAPD_MODE_IEEE80211A;
}
- if (freq > 5940 && freq <= 7105) {
+ if (freq > 5950 && freq <= 7115) {
int bw;
- u8 idx = (freq - 5940) / 5;
+ u8 idx = (freq - 5950) / 5;
bw = center_idx_to_bw_6ghz(idx);
if (bw < 0)
@@ -952,6 +952,12 @@
return HOSTAPD_MODE_IEEE80211A;
}
+ if (freq == 5935) {
+ *op_class = 136;
+ *channel = (freq - 5925) / 5;
+ return HOSTAPD_MODE_IEEE80211A;
+ }
+
/* 56.16 GHz, channel 1..6 */
if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
if (sec_channel)
@@ -1328,7 +1334,11 @@
case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
if (chan < 1 || chan > 233)
return -1;
- return 5940 + chan * 5;
+ return 5950 + chan * 5;
+ case 136: /* UHB channels, 20 MHz: 2 */
+ if (chan == 2)
+ return 5935;
+ return -1;
case 180: /* 60 GHz band, channels 1..8 */
if (chan < 1 || chan > 8)
return -1;
@@ -2117,10 +2127,13 @@
int is_6ghz_freq(int freq)
{
- if (freq < 5940 || freq > 7105)
+ if (freq < 5935 || freq > 7115)
return 0;
- if (center_idx_to_bw_6ghz((freq - 5940) / 5) < 0)
+ if (freq == 5935)
+ return 1;
+
+ if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
return 0;
return 1;
@@ -2129,7 +2142,7 @@
int is_6ghz_op_class(u8 op_class)
{
- return op_class >= 131 && op_class <= 135;
+ return op_class >= 131 && op_class <= 136;
}
@@ -2137,14 +2150,14 @@
{
int i;
- if (!is_6ghz_freq(freq))
+ if (!is_6ghz_freq(freq) || freq == 5935)
return 0;
- if ((((freq - 5940) / 5) & 0x3) != 0x1)
+ if ((((freq - 5950) / 5) & 0x3) != 0x1)
return 0;
- i = (freq - 5940 + 55) % 80;
+ i = (freq - 5950 + 55) % 80;
if (i == 0)
- i = (freq - 5940 + 55) / 80;
+ i = (freq - 5950 + 55) / 80;
if (i >= 1 && i <= 15)
return 1;
@@ -2380,6 +2393,8 @@
case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
return 160;
+ case 136: /* UHB channels, 20 MHz: 2 */
+ return 20;
case 180: /* 60 GHz band, channels 1..8 */
return 2160;
case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
@@ -2440,6 +2455,8 @@
return CHANWIDTH_160MHZ;
case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
return CHANWIDTH_80P80MHZ;
+ case 136: /* UHB channels, 20 MHz: 2 */
+ return CHANWIDTH_USE_HT;
case 180: /* 60 GHz band, channels 1..8 */
return CHANWIDTH_2160MHZ;
case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index b440497..ed20fb3 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -16,10 +16,6 @@
CONFIG_DRIVER_NL80211_QCA=y
endif
-ifeq ($(WIFI_UPDATE_SUPPLICANT_MAC_ADDR), enabled)
- FEATURE_UPDATE_STA_MAC_ADDR=y
-endif
-
include $(LOCAL_PATH)/android.config
# To ignore possible wrong network configurations
@@ -72,6 +68,10 @@
L_CFLAGS += -DCONFIG_NO_ROAMING
endif
+ifeq ($(WIFI_UPDATE_SUPPLICANT_MAC_ADDR), enabled)
+L_CFLAGS += -DFEATURE_UPDATE_STA_MAC_ADDR
+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/hidl/1.4/hidl_manager.cpp b/wpa_supplicant/hidl/1.4/hidl_manager.cpp
index 431881c..5e74f48 100644
--- a/wpa_supplicant/hidl/1.4/hidl_manager.cpp
+++ b/wpa_supplicant/hidl/1.4/hidl_manager.cpp
@@ -1236,9 +1236,8 @@
return;
// For group notifications, need to use the parent iface for callbacks.
- struct wpa_supplicant *wpa_s = wpa_group_s->parent;
- if (p2p_iface_object_map_.find(wpa_s->ifname) ==
- p2p_iface_object_map_.end())
+ struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+ if (!wpa_s)
return;
uint32_t hidl_freq = wpa_group_s->current_bss
@@ -1279,9 +1278,8 @@
return;
// For group notifications, need to use the parent iface for callbacks.
- struct wpa_supplicant *wpa_s = wpa_group_s->parent;
- if (p2p_iface_object_map_.find(wpa_s->ifname) ==
- p2p_iface_object_map_.end())
+ struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+ if (!wpa_s)
return;
bool hidl_is_go = (std::string(role) == "GO");
@@ -1386,15 +1384,15 @@
}
void HidlManager::notifyApStaAuthorized(
- struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+ struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
{
- if (!wpa_s || !wpa_s->parent || !sta)
+ if (!wpa_group_s || !wpa_group_s->parent || !sta)
return;
- if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
- p2p_iface_object_map_.end())
+ wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+ if (!wpa_s)
return;
callWithEachP2pIfaceCallback(
- wpa_s->parent->ifname,
+ wpa_s->ifname,
std::bind(
&ISupplicantP2pIfaceCallback::onStaAuthorized,
std::placeholders::_1, sta,
@@ -1402,16 +1400,16 @@
}
void HidlManager::notifyApStaDeauthorized(
- struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+ struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
{
- if (!wpa_s || !wpa_s->parent || !sta)
+ if (!wpa_group_s || !wpa_group_s->parent || !sta)
return;
- if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
- p2p_iface_object_map_.end())
+ wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+ if (!wpa_s)
return;
callWithEachP2pIfaceCallback(
- wpa_s->parent->ifname,
+ wpa_s->ifname,
std::bind(
&ISupplicantP2pIfaceCallback::onStaDeauthorized,
std::placeholders::_1, sta,
@@ -1976,6 +1974,35 @@
}
/**
+ * Finds the correct |wpa_supplicant| object for P2P notifications
+ *
+ * @param wpa_s the |wpa_supplicant| that triggered the P2P event.
+ * @return appropriate |wpa_supplicant| object or NULL if not found.
+ */
+struct wpa_supplicant *HidlManager::getTargetP2pIfaceForGroup(
+ struct wpa_supplicant *wpa_group_s)
+{
+ if (!wpa_group_s || !wpa_group_s->parent)
+ return NULL;
+
+ struct wpa_supplicant *target_wpa_s = wpa_group_s->parent;
+ if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
+ p2p_iface_object_map_.end())
+ return target_wpa_s;
+
+ // try P2P device if available
+ if (!target_wpa_s->p2pdev || !target_wpa_s->p2pdev->p2p_mgmt)
+ return NULL;
+
+ target_wpa_s = target_wpa_s->p2pdev;
+ if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
+ p2p_iface_object_map_.end())
+ return target_wpa_s;
+
+ return NULL;
+}
+
+/**
* Removes the provided |ISupplicantCallback| hidl object reference
* from our global callback list.
*
diff --git a/wpa_supplicant/hidl/1.4/hidl_manager.h b/wpa_supplicant/hidl/1.4/hidl_manager.h
index 9df7b55..e024427 100644
--- a/wpa_supplicant/hidl/1.4/hidl_manager.h
+++ b/wpa_supplicant/hidl/1.4/hidl_manager.h
@@ -185,6 +185,8 @@
HidlManager(const HidlManager &) = default;
HidlManager &operator=(const HidlManager &) = default;
+ struct wpa_supplicant *getTargetP2pIfaceForGroup(
+ struct wpa_supplicant *wpa_s);
void removeSupplicantCallbackHidlObject(
const android::sp<ISupplicantCallback> &callback);
void removeP2pIfaceCallbackHidlObject(
diff --git a/wpa_supplicant/hidl/1.4/p2p_iface.cpp b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
index ece1c04..8f4416c 100644
--- a/wpa_supplicant/hidl/1.4/p2p_iface.cpp
+++ b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
@@ -1083,8 +1083,9 @@
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
const char* pin =
pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
+ bool auto_join = !join_existing_group;
int new_pin = wpas_p2p_connect(
- wpa_s, peer_address.data(), pin, wps_method, persistent, false,
+ wpa_s, peer_address.data(), pin, wps_method, persistent, auto_join,
join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
if (new_pin < 0) {
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
index 983801f..bd97fee 100644
--- a/wpa_supplicant/op_classes.c
+++ b/wpa_supplicant/op_classes.c
@@ -22,13 +22,13 @@
unsigned int *flags)
{
int i;
- int is_6ghz = op_class >= 131 && op_class <= 135;
+ int is_6ghz = op_class >= 131 && op_class <= 136;
for (i = 0; i < mode->num_channels; i++) {
int chan_is_6ghz;
- chan_is_6ghz = mode->channels[i].freq > 5940 &&
- mode->channels[i].freq <= 7105;
+ chan_is_6ghz = mode->channels[i].freq >= 5935 &&
+ mode->channels[i].freq <= 7115;
if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
break;
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b0bea61..2d33810 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4925,6 +4925,15 @@
MAC2STR(wpa_s->pending_join_dev_addr));
return;
}
+ if (wpa_s->p2p_fallback_to_go_neg) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Join operating "
+ "failed - fall back to GO Negotiation");
+ wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
+ P2P_EVENT_FALLBACK_TO_GO_NEG
+ "reason=join-failed");
+ wpas_p2p_fallback_to_go_neg(wpa_s, 0);
+ return;
+ }
wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
P2P_EVENT_GROUP_FORMATION_FAILURE);
wpas_notify_p2p_group_formation_failure(wpa_s, "");
@@ -9383,6 +9392,12 @@
/* Stop the AP functionality */
/* TODO: Should do this in a way that does not indicated to possible
* P2P Clients in the group that the group is terminated. */
+ /* If this action occurs before a group is started, the callback should be
+ * preserved, or GROUP-STARTED event would be lost. If this action occurs after
+ * a group is started, these poiners are all NULL and harmless. */
+ void (*ap_configured_cb)(void *ctx, void *data) = wpa_s->ap_configured_cb;
+ void *ap_configured_cb_ctx = wpa_s->ap_configured_cb_ctx;;
+ void *ap_configured_cb_data = wpa_s->ap_configured_cb_data;
wpa_supplicant_ap_deinit(wpa_s);
/* Reselect the GO frequency */
@@ -9406,6 +9421,9 @@
return;
}
+ wpa_s->ap_configured_cb = ap_configured_cb;
+ wpa_s->ap_configured_cb_ctx = ap_configured_cb_ctx;
+ wpa_s->ap_configured_cb_data = ap_configured_cb_data;
/* Update the frequency */
current_ssid->frequency = params.freq;
wpa_s->connect_without_scan = current_ssid;