From: Ningyuan Wang Date: Thu, 15 Sep 2016 17:53:07 +0000 (-0700) Subject: Support fetching packet counters for wificond X-Git-Tag: android-x86-8.1-r1~109^2^2^2~12 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=a12253e46c1328548c4b37d7f365b4009a6e5776;p=android-x86%2Fsystem-connectivity-wificond.git Support fetching packet counters for wificond BUG=30978872 TEST=compile, manual tests Change-Id: Ifa0dd9ce794a1cdb6da7e357d6873992091e3ea0 --- diff --git a/aidl/android/net/wifi/IClientInterface.aidl b/aidl/android/net/wifi/IClientInterface.aidl index 1ba7e36..27f15e7 100644 --- a/aidl/android/net/wifi/IClientInterface.aidl +++ b/aidl/android/net/wifi/IClientInterface.aidl @@ -27,4 +27,9 @@ interface IClientInterface { // Remove this interface from wpa_supplicant's control. // Returns true if removal was successful. boolean disableSupplicant(); + + // Get packet counters for this interface. + // First element in array is the number of successfully transmitted packets. + // Second element in array is the number of tramsmission failure. + int[] getPacketCounters(); } diff --git a/client_interface_binder.cpp b/client_interface_binder.cpp index 557b673..52fb820 100644 --- a/client_interface_binder.cpp +++ b/client_interface_binder.cpp @@ -16,11 +16,14 @@ #include "wificond/client_interface_binder.h" +#include + #include #include "wificond/client_interface_impl.h" using android::binder::Status; +using std::vector; namespace android { namespace wificond { @@ -42,5 +45,15 @@ Status ClientInterfaceBinder::disableSupplicant(bool* success) { return Status::ok(); } +Status ClientInterfaceBinder::getPacketCounters( + vector* out_packet_counters) { + if (impl_ == nullptr) { + return Status::ok(); + } + impl_->GetPacketCounters(out_packet_counters); + return Status::ok(); +} + + } // namespace wificond } // namespace android diff --git a/client_interface_binder.h b/client_interface_binder.h index cd2a6fe..5bb2576 100644 --- a/client_interface_binder.h +++ b/client_interface_binder.h @@ -39,6 +39,8 @@ class ClientInterfaceBinder : public android::net::wifi::BnClientInterface { ::android::binder::Status enableSupplicant(bool* success) override; ::android::binder::Status disableSupplicant(bool* success) override; + ::android::binder::Status getPacketCounters( + std::vector* out_packet_counters) override; private: ClientInterfaceImpl* impl_; diff --git a/client_interface_impl.cpp b/client_interface_impl.cpp index 30b12e5..11927aa 100644 --- a/client_interface_impl.cpp +++ b/client_interface_impl.cpp @@ -23,6 +23,7 @@ #include #include "wificond/client_interface_binder.h" +#include "wificond/net/netlink_utils.h" #include "wificond/scanning/scan_result.h" #include "wificond/scanning/scan_utils.h" @@ -32,6 +33,7 @@ using android::wifi_system::SupplicantManager; using namespace std::placeholders; using std::string; +using std::unique_ptr; using std::vector; namespace android { @@ -42,11 +44,13 @@ ClientInterfaceImpl::ClientInterfaceImpl( uint32_t interface_index, const std::vector& interface_mac_addr, SupplicantManager* supplicant_manager, + NetlinkUtils* netlink_utils, ScanUtils* scan_utils) : interface_name_(interface_name), interface_index_(interface_index), interface_mac_addr_(interface_mac_addr), supplicant_manager_(supplicant_manager), + netlink_utils_(netlink_utils), scan_utils_(scan_utils), binder_(new ClientInterfaceBinder(this)) { scan_utils_->SubscribeScanResultNotification( @@ -72,6 +76,18 @@ bool ClientInterfaceImpl::DisableSupplicant() { return supplicant_manager_->StopSupplicant(); } +bool ClientInterfaceImpl::GetPacketCounters(vector* out_packet_counters) { + StationInfo station_info; + if(!netlink_utils_->GetStationInfo(interface_index_, + interface_mac_addr_, + &station_info)) { + return false; + } + out_packet_counters->push_back(station_info.station_tx_packets); + out_packet_counters->push_back(station_info.station_tx_failed); + return true; +} + void ClientInterfaceImpl::OnScanResultsReady( uint32_t interface_index, std::vector>& ssids, diff --git a/client_interface_impl.h b/client_interface_impl.h index b6334cb..af1c316 100644 --- a/client_interface_impl.h +++ b/client_interface_impl.h @@ -29,6 +29,7 @@ namespace android { namespace wificond { class ClientInterfaceBinder; +class NetlinkUtils; class ScanUtils; // Holds the guts of how we control network interfaces capable of connecting to @@ -44,6 +45,7 @@ class ClientInterfaceImpl { uint32_t interface_index, const std::vector& interface_mac_addr, android::wifi_system::SupplicantManager* supplicant_manager, + NetlinkUtils* netlink_utils, ScanUtils* scan_utils); ~ClientInterfaceImpl(); @@ -52,6 +54,7 @@ class ClientInterfaceImpl { bool EnableSupplicant(); bool DisableSupplicant(); + bool GetPacketCounters(std::vector* out_packet_counters); private: void OnScanResultsReady(uint32_t interface_index, @@ -62,6 +65,7 @@ class ClientInterfaceImpl { const uint32_t interface_index_; const std::vector interface_mac_addr_; android::wifi_system::SupplicantManager* const supplicant_manager_; + NetlinkUtils* const netlink_utils_; ScanUtils* const scan_utils_; const android::sp binder_; diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp index f79a6cd..a1a4e24 100644 --- a/net/netlink_utils.cpp +++ b/net/netlink_utils.cpp @@ -191,7 +191,8 @@ bool NetlinkUtils::GetWiphyInfo( } if (response->GetMessageType() == NLMSG_ERROR) { LOG(ERROR) << "Receive ERROR message: " - << strerror(response->GetErrorCode()) << "in response to a GetWiphy request"; + << strerror(response->GetErrorCode()) + << "in response to a GetWiphy request"; return false; } if (response->GetCommand() != NL80211_CMD_NEW_WIPHY) { @@ -287,7 +288,7 @@ bool NetlinkUtils::ParseBandInfo(const NL80211Packet* const packet, // Since there is no guarantee for the order of band attributes, // we do some math here. if (frequency_value > k2GHzFrequencyLowerBound && - frequency_value < k2GHzFrequencyUpperBound ) { + frequency_value < k2GHzFrequencyUpperBound) { frequencies_2g.push_back(frequency_value); } else { frequencies_5g.push_back(frequency_value); @@ -299,5 +300,54 @@ bool NetlinkUtils::ParseBandInfo(const NL80211Packet* const packet, return true; } +bool NetlinkUtils::GetStationInfo(uint32_t interface_index, + const vector& mac_address, + StationInfo* out_station_info) { + NL80211Packet get_station( + netlink_manager_->GetFamilyId(), + NL80211_CMD_GET_STATION, + netlink_manager_->GetSequenceNumber(), + getpid()); + get_station.AddAttribute(NL80211Attr(NL80211_ATTR_IFINDEX, + interface_index)); + get_station.AddAttribute(NL80211Attr>(NL80211_ATTR_MAC, + mac_address)); + + unique_ptr response; + if (!netlink_manager_->SendMessageAndGetSingleResponse(get_station, + &response)) { + LOG(ERROR) << "Failed to get packet counters"; + return false; + } + if (response->GetMessageType() == NLMSG_ERROR) { + LOG(ERROR) << "Receive ERROR message: " + << strerror(response->GetErrorCode()) + << "in response to a get station request"; + return false; + } + + if (response->GetCommand() != NL80211_CMD_NEW_STATION) { + LOG(ERROR) << "Wrong command in response to a get station request: " + << static_cast(response->GetCommand()); + return false; + } + NL80211NestedAttr sta_info(0); + if (!response->GetAttribute(NL80211_ATTR_STA_INFO, &sta_info)) { + LOG(ERROR) << "Failed to get NL80211_ATTR_STA_INFO"; + return false; + } + int32_t tx_good, tx_bad; + if (!sta_info.GetAttributeValue(NL80211_STA_INFO_TX_PACKETS, &tx_good)) { + LOG(ERROR) << "Failed to get NL80211_STA_INFO_TX_PACKETS"; + return false; + } + if (!sta_info.GetAttributeValue(NL80211_STA_INFO_TX_FAILED, &tx_bad)) { + LOG(ERROR) << "Failed to get NL80211_STA_INFO_TX_FAILED"; + return false; + } + *out_station_info = StationInfo(tx_good, tx_bad); + return true; +} + } // namespace wificond } // namespace android diff --git a/net/netlink_utils.h b/net/netlink_utils.h index 41cb41b..91690f9 100644 --- a/net/netlink_utils.h +++ b/net/netlink_utils.h @@ -57,6 +57,20 @@ struct ScanCapabilities { uint8_t max_match_sets; }; +struct StationInfo { + StationInfo() = default; + StationInfo(uint32_t station_tx_packets_, + uint32_t station_tx_failed_) + : station_tx_packets(station_tx_packets_), + station_tx_failed(station_tx_failed_) {} + // Number of successfully transmitted packets. + int32_t station_tx_packets; + // number of tramsmission failures. + int32_t station_tx_failed; + // There are many other counters/parameters included in station info. + // We will add them once we find them useful. +}; + class NetlinkManager; class NL80211Packet; @@ -79,10 +93,22 @@ class NetlinkUtils { uint32_t* index, std::vector* mac_addr); + // Get wifi wiphy info from kernel. + // |*out_band_info| is the lists of frequencies in specific bands. + // |*out_scan_capabilities| is the lists of parameters specifying the + // scanning capability of underlying implementation. + // Returns true on success. virtual bool GetWiphyInfo(uint32_t wiphy_index, BandInfo* out_band_info, ScanCapabilities* out_scan_capabilities); + // Get station info from kernel. + // |*out_station_info]| is the struct of available station information. + // Returns true on success. + virtual bool GetStationInfo(uint32_t interface_index, + const std::vector& mac_address, + StationInfo* out_station_info); + private: bool ParseBandInfo(const NL80211Packet* const packet, BandInfo* out_band_info); diff --git a/server.cpp b/server.cpp index 1813e20..9eef6f4 100644 --- a/server.cpp +++ b/server.cpp @@ -122,6 +122,7 @@ Status Server::createClientInterface(sp* created_interface) { interface_index, interface_mac_addr, supplicant_manager_.get(), + netlink_utils_, scan_utils_)); *created_interface = client_interface->GetBinder(); client_interfaces_.push_back(std::move(client_interface)); diff --git a/tests/client_interface_impl_unittest.cpp b/tests/client_interface_impl_unittest.cpp index c43b62f..7dd0f23 100644 --- a/tests/client_interface_impl_unittest.cpp +++ b/tests/client_interface_impl_unittest.cpp @@ -24,6 +24,7 @@ #include "wificond/client_interface_impl.h" #include "wificond/tests/mock_netlink_manager.h" +#include "wificond/tests/mock_netlink_utils.h" #include "wificond/tests/mock_scan_utils.h" using android::wifi_system::MockSupplicantManager; @@ -53,6 +54,7 @@ class ClientInterfaceImplTest : public ::testing::Test { kTestInterfaceIndex, vector{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, supplicant_manager_.get(), + &netlink_utils_, &scan_utils_}); } @@ -68,6 +70,7 @@ class ClientInterfaceImplTest : public ::testing::Test { new NiceMock}; unique_ptr> netlink_manager_{ new NiceMock()}; + MockNetlinkUtils netlink_utils_{netlink_manager_.get()}; MockScanUtils scan_utils_{netlink_manager_.get()}; unique_ptr client_interface_; }; // class ClientInterfaceImplTest