STA/AP Concurrency fails with the wifi which has multiple phy
As the issue tracker: https://issuetracker.google.com/issues/122429718 The current Android P framework doesn't support the wifi devices with multiple phy's. Suppose that the wifi has two or more wiphys. (e.g. wlan0 - phy#0 - ifindex 6, and wlan1 - phy#1 - ifindex 8) And the system is built with WIFI_HIDL_FEATURE_DUAL_INTERFACE := true PRODUCT_PROPERTY_OVERRIDES += wifi.interface=wlan0 PRODUCT_PROPERTY_OVERRIDES += wifi.concurrent.interface=wlan1 At first, we connected to one AP successfully, and then we tried to start hotspot, but the hotspot can not be enabled. After checking, we found that in the Android P source code, setupInterfaceForSoftApMode() => mWificond.createApInterface(ifaceName) // wificond/server.cpp ==> SetupInterface(iface_name, &interface) ===> !RefreshWiphyIndex() ====> netlink_utils_->GetWiphyIndex(&wiphy_index_) The iface_name here, assigned by upper Android framework, is wlan1 as expected. Meanwhile, in the GetWiphyIndex(), it uses NL80211_CMD_GET_WIPHY command, with flag - NLM_F_DUMP, it doesn't assign NL80211_ATTR_IFINDEX, so the results have all the wiphy, and eventually return the last one phy#0, instead of phy#1. Then in server.cpp::SetupInterface(), wiphy_index_ is assigned to 0, it can not find wlan1, since wlan1's wiphy number is 1, not 0. Thus it fails. So we would like to suggest to add parameter NL80211_ATTR_IFINDEX in the function GetWiphyIndex(), for the command NL80211_CMD_GET_WIPHY, then it can find the correct wiphy number phy#1, instead of phy#0, when using interface wlan1. In the NetlinkUtils::GetWiphyIndex(), we add one more parameter, string iface_name. And if the string is empty, it means we use the original way to do GetWiphyIndex; If the string is not empty, it will add attribute NL80211_ATTR_IFINDEX for NL80211_CMD_GET_WIPHY. Test: built, tested manually with the wifi which has two phy Change-Id: I9319633d0ef220b9ba4a226ee5446bef08e4ac78 Signed-off-by: Neo Jou <neojou@gmail.com>
This commit is contained in:
parent
69da09ec61
commit
3e76438803
|
@ -21,6 +21,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
@ -98,13 +99,18 @@ NetlinkUtils::NetlinkUtils(NetlinkManager* netlink_manager)
|
|||
|
||||
NetlinkUtils::~NetlinkUtils() {}
|
||||
|
||||
bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index) {
|
||||
bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index,
|
||||
const std::string& iface_name) {
|
||||
NL80211Packet get_wiphy(
|
||||
netlink_manager_->GetFamilyId(),
|
||||
NL80211_CMD_GET_WIPHY,
|
||||
netlink_manager_->GetSequenceNumber(),
|
||||
getpid());
|
||||
get_wiphy.AddFlag(NLM_F_DUMP);
|
||||
if (!iface_name.empty()) {
|
||||
int ifindex = if_nametoindex(iface_name.c_str());
|
||||
get_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, ifindex));
|
||||
}
|
||||
vector<unique_ptr<const NL80211Packet>> response;
|
||||
if (!netlink_manager_->SendMessageAndGetResponses(get_wiphy, &response)) {
|
||||
LOG(ERROR) << "NL80211_CMD_GET_WIPHY dump failed";
|
||||
|
@ -139,6 +145,10 @@ bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index) {
|
||||
return GetWiphyIndex(out_wiphy_index, "");
|
||||
}
|
||||
|
||||
bool NetlinkUtils::GetInterfaces(uint32_t wiphy_index,
|
||||
vector<InterfaceInfo>* interface_info) {
|
||||
NL80211Packet get_interfaces(
|
||||
|
|
|
@ -157,6 +157,8 @@ class NetlinkUtils {
|
|||
// |*out_wiphy_index| returns the wiphy index from kernel.
|
||||
// Returns true on success.
|
||||
virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
|
||||
virtual bool GetWiphyIndex(uint32_t* out_wiphy_index,
|
||||
const std::string& iface_name);
|
||||
|
||||
// Get wifi interfaces info from kernel.
|
||||
// |wiphy_index| is the wiphy index we get using GetWiphyIndex().
|
||||
|
|
|
@ -315,7 +315,7 @@ Status Server::getAvailableDFSChannels(
|
|||
|
||||
bool Server::SetupInterface(const std::string& iface_name,
|
||||
InterfaceInfo* interface) {
|
||||
if (!RefreshWiphyIndex()) {
|
||||
if (!RefreshWiphyIndex(iface_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -342,8 +342,8 @@ bool Server::SetupInterface(const std::string& iface_name,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Server::RefreshWiphyIndex() {
|
||||
if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
|
||||
bool Server::RefreshWiphyIndex(const std::string& iface_name) {
|
||||
if (!netlink_utils_->GetWiphyIndex(&wiphy_index_, iface_name)) {
|
||||
LOG(ERROR) << "Failed to get wiphy index";
|
||||
return false;
|
||||
}
|
||||
|
|
2
server.h
2
server.h
|
@ -102,7 +102,7 @@ class Server : public android::net::wifi::BnWificond {
|
|||
// the interface to Ap mode later.
|
||||
// Returns true on success, false otherwise.
|
||||
bool SetupInterface(const std::string& iface_name, InterfaceInfo* interface);
|
||||
bool RefreshWiphyIndex();
|
||||
bool RefreshWiphyIndex(const std::string& iface_num);
|
||||
void LogSupportedBands();
|
||||
void OnRegDomainChanged(std::string& country_code);
|
||||
void BroadcastClientInterfaceReady(
|
||||
|
|
Loading…
Reference in New Issue