[automerger skipped] Merge "DO NOT MERGE - Merge Android 13" am: dc87a07954 -s ours am: 403837954c -s ours am: 855e8ad09a -s ours am: 1e9a82c15a -s ours

am skip reason: Merged-In If550b000a40608832d42dac4f3010db87e3800bc with SHA-1 3dec16bf85 is already in history

Original change: https://android-review.googlesource.com/c/platform/system/connectivity/wificond/+/2186885

Change-Id: If223cbb7d721811a03c395d617776e6a320d6bb4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/client_interface_impl.cpp b/client_interface_impl.cpp
index 26bcba3..cd50e22 100644
--- a/client_interface_impl.cpp
+++ b/client_interface_impl.cpp
@@ -242,6 +242,16 @@
   return interface_mac_addr_;
 }
 
+void ClientInterfaceImpl::UpdateBandInfo() {
+  LOG(INFO) << "UpdateBandInfo";
+  if (!netlink_utils_->GetWiphyInfo(wiphy_index_,
+                               &band_info_,
+                               &scan_capabilities_,
+                               &wiphy_features_)) {
+    LOG(ERROR) << "Failed to get wiphy info from kernel";
+  }
+}
+
 const BandInfo& ClientInterfaceImpl::GetBandInfo() const {
   return band_info_;
 }
diff --git a/client_interface_impl.h b/client_interface_impl.h
index c52c2b0..9711a8c 100644
--- a/client_interface_impl.h
+++ b/client_interface_impl.h
@@ -78,6 +78,7 @@
   bool SignalPoll(std::vector<int32_t>* out_signal_poll_results);
   const std::array<uint8_t, ETH_ALEN>& GetMacAddress();
   const std::string& GetInterfaceName() const { return interface_name_; }
+  void UpdateBandInfo();
   const BandInfo& GetBandInfo() const;
   const android::sp<ScannerImpl> GetScanner() { return scanner_; };
   virtual bool IsAssociated() const;
diff --git a/net/netlink_manager.cpp b/net/netlink_manager.cpp
index 64db5d8..95d8a46 100644
--- a/net/netlink_manager.cpp
+++ b/net/netlink_manager.cpp
@@ -48,7 +48,7 @@
 // netlink.h suggests NLMSG_GOODSIZE to be at most 8192 bytes.
 constexpr int kReceiveBufferSize = 8 * 1024;
 constexpr uint32_t kBroadcastSequenceNumber = 0;
-constexpr int kMaximumNetlinkMessageWaitMilliSeconds = 1000;
+constexpr int kMaximumNetlinkMessageWaitMilliSeconds = 4000;
 uint8_t ReceiveBuffer[kReceiveBufferSize];
 
 void AppendPacket(vector<unique_ptr<const NL80211Packet>>* vec,
@@ -99,7 +99,8 @@
 void NetlinkManager::ReceivePacketAndRunHandler(int fd) {
   ssize_t len = read(fd, ReceiveBuffer, kReceiveBufferSize);
   if (len == -1) {
-    LOG(ERROR) << "Failed to read packet from buffer on fd: " << fd;
+    LOG(ERROR) << "Failed to read packet from buffer on fd: " << fd
+               << ", error is " << strerror(errno);
     perror(" netlink error ");
     return;
   }
@@ -136,7 +137,8 @@
     auto itr = message_handlers_.find(sequence_number);
     // There is no handler for this sequence number.
     if (itr == message_handlers_.end()) {
-      LOG(WARNING) << "No handler for message: " << sequence_number;
+      LOG(WARNING) << "No handler for message: " << sequence_number
+                   << ", packet len = " << len;
       return;
     }
     // A multipart message is terminated by NLMSG_DONE.
@@ -308,11 +310,13 @@
                            time_remaining);
 
     if (poll_return == 0) {
-      LOG(ERROR) << "Failed to poll netlink fd:" << sync_netlink_fd_.get() << "time out ";
+      LOG(ERROR) << "Failed to poll netlink fd:" << sync_netlink_fd_.get()
+                 << "time out, sequence is " << sequence ;
       message_handlers_.erase(sequence);
       return false;
     } else if (poll_return == -1) {
-      PLOG(ERROR) << "Failed to poll netlink fd";
+      LOG(ERROR) << "Failed to poll netlink fd:" << sync_netlink_fd_.get()
+                 << ", sequence is " << sequence;
       message_handlers_.erase(sequence);
       return false;
     }
@@ -321,7 +325,7 @@
     time_remaining -= static_cast<int>(ns2ms(interval));
   }
   if (time_remaining <= 0) {
-    LOG(ERROR) << "Timeout waiting for netlink reply messages";
+    LOG(ERROR) << "Timeout waiting for netlink reply messages, sequence is " << sequence;
     message_handlers_.erase(sequence);
     return false;
   }
diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp
index bf824b3..fc705d6 100644
--- a/net/netlink_utils.cpp
+++ b/net/netlink_utils.cpp
@@ -73,6 +73,7 @@
 
 constexpr uint8_t kEhtCapPhyNumByte = 8;
 constexpr uint8_t kEht320MhzBitMask = 0x2;
+constexpr int kNl80211CmdRetryCount = 1;
 
 bool IsExtFeatureFlagSet(
     const std::vector<uint8_t>& ext_feature_flags_bytes,
@@ -135,7 +136,7 @@
       netlink_manager_->GetSequenceNumber(),
       getpid());
   get_wiphy.AddFlag(NLM_F_DUMP);
-  int ifindex;
+  int ifindex = 0;
   if (!iface_name.empty()) {
     ifindex = if_nametoindex(iface_name.c_str());
     if (ifindex == 0) {
@@ -145,11 +146,20 @@
     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, ifindex: "
-               << ifindex << " and name: " << iface_name.c_str();
-    return false;
+  for (int i = kNl80211CmdRetryCount; i >= 0; i--) {
+      if (netlink_manager_->SendMessageAndGetResponses(get_wiphy, &response))  {
+          break;
+      } else {
+        if (i == 0) {
+            LOG(ERROR) << "NL80211_CMD_GET_WIPHY dump failed, ifindex: "
+                       << ifindex << " and name: " << iface_name.c_str();
+            return false;
+        } else {
+            LOG(INFO) << "Failed to get wiphy index, retry again";
+        }
+      }
   }
+
   if (response.empty()) {
     LOG(INFO) << "No wiphy is found";
     return false;
@@ -320,9 +330,17 @@
     get_wiphy.AddFlag(NLM_F_DUMP);
   }
   vector<unique_ptr<const NL80211Packet>> response;
-  if (!netlink_manager_->SendMessageAndGetResponses(get_wiphy, &response))  {
-    LOG(ERROR) << "NL80211_CMD_GET_WIPHY dump failed";
-    return false;
+  for (int i = kNl80211CmdRetryCount; i >= 0; i--) {
+      if (netlink_manager_->SendMessageAndGetResponses(get_wiphy, &response))  {
+          break;
+      } else {
+        if (i == 0) {
+            LOG(ERROR) << "NL80211_CMD_GET_WIPHY dump failed";
+            return false;
+        } else {
+            LOG(INFO) << "Failed to get wiphy info, retry again";
+        }
+      }
   }
 
   vector<NL80211Packet> packet_per_wiphy;
diff --git a/server.cpp b/server.cpp
index 1fd10dd..9b6bc38 100644
--- a/server.cpp
+++ b/server.cpp
@@ -18,6 +18,7 @@
 
 #include <algorithm> // for std::find_if
 #include <sstream>
+#include <set>
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
@@ -44,6 +45,7 @@
 using std::optional;
 using std::placeholders::_1;
 using std::placeholders::_2;
+using std::set;
 using std::string;
 using std::stringstream;
 using std::unique_ptr;
@@ -487,6 +489,30 @@
   return false;
 }
 
+void Server::handleCountryCodeChanged() {
+  uint32_t wiphy_index;
+  set<uint32_t> handled_wiphy_index;
+  for (auto& it : client_interfaces_) {
+    it.second->UpdateBandInfo();
+    if (netlink_utils_->GetWiphyIndex(&wiphy_index, it.first)) {
+      if (handled_wiphy_index.find(wiphy_index) == handled_wiphy_index.end()) {
+        UpdateBandWiphyIndexMap(wiphy_index);
+        LogSupportedBands(wiphy_index);
+        handled_wiphy_index.insert(wiphy_index);
+      }
+    }
+  }
+  for (auto& it : ap_interfaces_) {
+    if (netlink_utils_->GetWiphyIndex(&wiphy_index, it.first)) {
+      if (handled_wiphy_index.find(wiphy_index) == handled_wiphy_index.end()) {
+        UpdateBandWiphyIndexMap(wiphy_index);
+        LogSupportedBands(wiphy_index);
+        handled_wiphy_index.insert(wiphy_index);
+      }
+    }
+  }
+}
+
 void Server::OnRegDomainChanged(uint32_t wiphy_index, std::string& country_code) {
   string current_country_code;
   if (country_code.empty()) {
@@ -506,26 +532,13 @@
   // interfaces. So update band - wiphy index mapping only if an
   // interface exists
   if (!hasNoIfaceForWiphyIndex(wiphy_index)) {
-    UpdateBandWiphyIndexMap(wiphy_index);
+    handleCountryCodeChanged();
   }
-  LogSupportedBands(wiphy_index);
 }
 
 android::binder::Status Server::notifyCountryCodeChanged() {
   LOG(INFO) << "Receive notifyCountryCodeChanged";
-  uint32_t wiphy_index;
-  for (auto& it : client_interfaces_) {
-    if (netlink_utils_->GetWiphyIndex(&wiphy_index, it.first)) {
-      UpdateBandWiphyIndexMap(wiphy_index);
-      LogSupportedBands(wiphy_index);
-    }
-  }
-  for (auto& it : ap_interfaces_) {
-    if (netlink_utils_->GetWiphyIndex(&wiphy_index, it.first)) {
-      UpdateBandWiphyIndexMap(wiphy_index);
-      LogSupportedBands(wiphy_index);
-    }
-  }
+  handleCountryCodeChanged();
   return Status::ok();
 }
 
diff --git a/server.h b/server.h
index b43ae0a..df0968c 100644
--- a/server.h
+++ b/server.h
@@ -121,6 +121,7 @@
       uint32_t *wiphy_index);
   void LogSupportedBands(uint32_t wiphy_index);
   void OnRegDomainChanged(uint32_t wiphy_index, std::string& country_code);
+  void handleCountryCodeChanged();
   void BroadcastClientInterfaceReady(
       android::sp<android::net::wifi::nl80211::IClientInterface> network_interface);
   void BroadcastApInterfaceReady(