| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef WIFICOND_NET_NETLINK_UTILS_H_ |
| #define WIFICOND_NET_NETLINK_UTILS_H_ |
| |
| #include <array> |
| #include <functional> |
| #include <string> |
| #include <vector> |
| |
| #include <linux/if_ether.h> |
| |
| #include <android-base/macros.h> |
| |
| #include "wificond/net/kernel-header-latest/nl80211.h" |
| #include "wificond/net/netlink_manager.h" |
| #include "wificond/net/nl80211_packet.h" |
| |
| namespace android { |
| namespace wificond { |
| |
| struct InterfaceInfo { |
| InterfaceInfo() = default; |
| InterfaceInfo(uint32_t if_index, |
| uint32_t wiphy_index, |
| const std::string& name, |
| const std::array<uint8_t, ETH_ALEN>& mac_address) |
| : if_index(if_index), |
| wiphy_index(wiphy_index), |
| name(name), |
| mac_address(mac_address) {} |
| // Index of this interface. |
| uint32_t if_index; |
| // Wiphy Index of this interface. |
| uint32_t wiphy_index; |
| // Name of this interface. |
| std::string name; |
| // MAC address of this interface. |
| std::array<uint8_t, ETH_ALEN> mac_address; |
| }; |
| |
| struct BandInfo { |
| BandInfo(): |
| is_80211n_supported(false), |
| is_80211ac_supported(false), |
| is_80211ax_supported(false), |
| is_80211be_supported(false), |
| is_160_mhz_supported(false), |
| is_80p80_mhz_supported(false), |
| is_320_mhz_supported(false), |
| max_tx_streams(1), |
| max_rx_streams(1) {}; |
| // Frequencies for 2.4 GHz band. |
| std::vector<uint32_t> band_2g; |
| // Frequencies for 5 GHz band without DFS. |
| std::vector<uint32_t> band_5g; |
| // Frequencies for DFS. |
| std::vector<uint32_t> band_dfs; |
| // Frequencies for 6 GHz band. |
| std::vector<uint32_t> band_6g; |
| // Frequencies for 60 GHz band. |
| std::vector<uint32_t> band_60g; |
| // support for 802.11n |
| bool is_80211n_supported; |
| // support for 802.11ac |
| bool is_80211ac_supported; |
| // support for 802.11ax |
| bool is_80211ax_supported; |
| // support for 802.11be |
| bool is_80211be_supported; |
| // support for 160Mhz channel width |
| bool is_160_mhz_supported; |
| // support for 80+80Mhz channel width |
| bool is_80p80_mhz_supported; |
| // support for 320Mhz channel width |
| bool is_320_mhz_supported; |
| // Max number of transmit spatial streams |
| uint32_t max_tx_streams; |
| // Max number of receive spatial streams |
| uint32_t max_rx_streams; |
| }; |
| |
| struct ScanCapabilities { |
| ScanCapabilities() = default; |
| ScanCapabilities(uint8_t max_num_scan_ssids_, |
| uint8_t max_num_sched_scan_ssids_, |
| uint8_t max_match_sets_, |
| uint32_t max_num_scan_plans_, |
| uint32_t max_scan_plan_interval_, |
| uint32_t max_scan_plan_iterations_) |
| : max_num_scan_ssids(max_num_scan_ssids_), |
| max_num_sched_scan_ssids(max_num_sched_scan_ssids_), |
| max_match_sets(max_match_sets_), |
| max_num_scan_plans(max_num_scan_plans_), |
| max_scan_plan_interval(max_scan_plan_interval_), |
| max_scan_plan_iterations(max_scan_plan_iterations_) {} |
| // Number of SSIDs you can scan with a single scan request. |
| uint8_t max_num_scan_ssids; |
| // Number of SSIDs you can scan with a single scheduled scan request. |
| uint8_t max_num_sched_scan_ssids; |
| // Maximum number of sets that can be used with NL80211_ATTR_SCHED_SCAN_MATCH. |
| uint8_t max_match_sets; |
| // Maximum number of scan plans that can be specified. |
| uint32_t max_num_scan_plans; |
| // Maximum interval in seconds for a particular scan plan that can be |
| // specified. |
| uint32_t max_scan_plan_interval; |
| // Maximum number of iterations for a particular scan plan that can be |
| // specified. |
| uint32_t max_scan_plan_iterations; |
| }; |
| |
| struct WiphyFeatures { |
| WiphyFeatures() |
| : supports_random_mac_oneshot_scan(false), |
| supports_random_mac_sched_scan(false), |
| supports_low_span_oneshot_scan(false), |
| supports_low_power_oneshot_scan(false), |
| supports_high_accuracy_oneshot_scan(false), |
| supports_tx_mgmt_frame_mcs(false) {} |
| WiphyFeatures(uint32_t feature_flags, |
| const std::vector<uint8_t>& ext_feature_flags_bytes); |
| // This device/driver supports using a random MAC address during scan |
| // (while not associated). |
| bool supports_random_mac_oneshot_scan; |
| // This device/driver supports using a random MAC address for every |
| // scan iteration during scheduled scan (while not associated). |
| bool supports_random_mac_sched_scan; |
| // This device/driver supports performing low-span/low-latency one-shot scans. |
| bool supports_low_span_oneshot_scan; |
| // This device/driver supports performing low-power one-shot scans. |
| bool supports_low_power_oneshot_scan; |
| // This device/driver supports performing high-accuracy one-shot scans. |
| bool supports_high_accuracy_oneshot_scan; |
| // This device/driver supports sending a management frame at a specified MCS. |
| bool supports_tx_mgmt_frame_mcs; |
| // This device/driver supports sched_scan for reporting BSSs |
| // with better RSSI than the current connected BSS |
| bool supports_ext_sched_scan_relative_rssi; |
| // There are other flags included in NL80211_ATTR_FEATURE_FLAGS. |
| // We will add them once we find them useful. |
| }; |
| |
| struct StationInfo { |
| StationInfo() = default; |
| StationInfo(uint32_t station_tx_packets_, |
| uint32_t station_tx_failed_, |
| uint32_t station_tx_bitrate_, |
| int8_t current_rssi_, |
| uint32_t station_rx_bitrate_) |
| : station_tx_packets(station_tx_packets_), |
| station_tx_failed(station_tx_failed_), |
| station_tx_bitrate(station_tx_bitrate_), |
| current_rssi(current_rssi_), |
| station_rx_bitrate(station_rx_bitrate_) {} |
| // Number of successfully transmitted packets. |
| int32_t station_tx_packets; |
| // Number of tramsmission failures. |
| int32_t station_tx_failed; |
| // Transimission bit rate in 100kbit/s. |
| uint32_t station_tx_bitrate; |
| // Current signal strength. |
| int8_t current_rssi; |
| // Last Received unicast packet bit rate in 100kbit/s. |
| uint32_t station_rx_bitrate; |
| // There are many other counters/parameters included in station info. |
| // We will add them once we find them useful. |
| }; |
| |
| class MlmeEventHandler; |
| class NetlinkManager; |
| class NL80211Packet; |
| |
| // Provides NL80211 helper functions. |
| class NetlinkUtils { |
| public: |
| // Currently we only support setting the interface to STATION mode. |
| // This is used for cleaning up interface after KILLING hostapd. |
| enum InterfaceMode{ |
| STATION_MODE |
| }; |
| |
| explicit NetlinkUtils(NetlinkManager* netlink_manager); |
| virtual ~NetlinkUtils(); |
| |
| // Get the wiphy index from kernel. |
| // |*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(). |
| // |interface_info| returns a vector of InterfaceInfo structs with |
| // information about all existing interfaces. |
| // Returns true on success. |
| virtual bool GetInterfaces(uint32_t wiphy_index, |
| std::vector<InterfaceInfo>* interface_info); |
| |
| // Set the mode of interface. |
| // |interface_index| is the interface index. |
| // |mode| is one of the values in |enum InterfaceMode|. |
| // Returns true on success. |
| virtual bool SetInterfaceMode(uint32_t interface_index, |
| InterfaceMode mode); |
| |
| // Get wiphy capability information from kernel. |
| // Returns true on success. |
| virtual bool GetWiphyInfo(uint32_t wiphy_index, |
| BandInfo* out_band_info, |
| ScanCapabilities* out_scan_capabilities, |
| WiphyFeatures* out_wiphy_features); |
| |
| // 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::array<uint8_t, ETH_ALEN>& mac_address, |
| StationInfo* out_station_info); |
| |
| // Get a bitmap for nl80211 protocol features, |
| // i.e. features for the nl80211 protocol rather than device features. |
| // See enum nl80211_protocol_features in nl80211.h for decoding the bitmap. |
| // Returns true on success. |
| virtual bool GetProtocolFeatures(uint32_t* features); |
| |
| // Get current alpha2 country code from kernel. |
| // Returns true on success. |
| virtual bool GetCountryCode(std::string* out_country_code); |
| |
| // Sign up to be notified when there is MLME event. |
| // Only one handler can be registered per interface index. |
| // New handler will replace the registered handler if they are for the |
| // same interface index. |
| // NetlinkUtils is not going to take ownership of this pointer, and that it |
| // is the caller's responsibility to make sure that the object exists for the |
| // duration of the subscription. |
| virtual void SubscribeMlmeEvent(uint32_t interface_index, |
| MlmeEventHandler* handler); |
| |
| // Cancel the sign-up of receiving MLME event notification |
| // from interface with index |interface_index|. |
| virtual void UnsubscribeMlmeEvent(uint32_t interface_index); |
| |
| // Sign up to be notified when there is an regulatory domain change. |
| // Only one handler can be registered per wiphy index. |
| // New handler will replace the registered handler if they are for the |
| // same wiphy index. |
| virtual void SubscribeRegDomainChange(uint32_t wiphy_index, |
| OnRegDomainChangedHandler handler); |
| |
| // Cancel the sign-up of receiving regulatory domain change notification |
| // from wiphy with index |wiphy_index|. |
| virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index); |
| |
| // Sign up to be notified when there is a station event. |
| // Only one handler can be registered per interface index. |
| // New handler will replace the registered handler if they are for the |
| // same interface index. |
| virtual void SubscribeStationEvent(uint32_t interface_index, |
| OnStationEventHandler handler); |
| |
| // Cancel the sign-up of receiving station events. |
| virtual void UnsubscribeStationEvent(uint32_t interface_index); |
| |
| // Sign up to be notified when there is a channel switch event. |
| // Only one handler can be registered per interface index. |
| // New handler will replace the registered handler if they are for the |
| // same interface index. |
| virtual void SubscribeChannelSwitchEvent(uint32_t interface_index, |
| OnChannelSwitchEventHandler handler); |
| |
| // Cancel the sign-up of receiving channel switch events. |
| virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index); |
| |
| // Sign up to be notified of frame tx status events. |
| virtual void SubscribeFrameTxStatusEvent( |
| uint32_t interface_index, OnFrameTxStatusEventHandler handler); |
| |
| // Cancel the sign-up of receiving frame tx status events. |
| virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index); |
| |
| virtual bool SendMgmtFrame(uint32_t interface_index, |
| const std::vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie); |
| |
| // Visible for testing. |
| bool supports_split_wiphy_dump_; |
| |
| private: |
| bool ParseWiphyInfoFromPacket( |
| const NL80211Packet& packet, |
| BandInfo* out_band_info, |
| ScanCapabilities* out_scan_capabilities, |
| WiphyFeatures* out_wiphy_features); |
| bool ParseBandInfo(const NL80211Packet* const packet, |
| BandInfo* out_band_info); |
| void ParseIfTypeDataAttributes(const NL80211NestedAttr& iftype_data_attr, |
| BandInfo* out_band_info); |
| void ParseHtVhtPhyCapabilities(const NL80211NestedAttr& band, |
| BandInfo* out_band_info); |
| void ParseHtMcsSetAttribute(const NL80211NestedAttr& band, |
| BandInfo* out_band_info); |
| void ParseVhtMcsSetAttribute(const NL80211NestedAttr& band, |
| BandInfo* out_band_info); |
| void ParseHeMcsSetAttribute(const NL80211NestedAttr& attribute, |
| BandInfo* out_band_info); |
| std::pair<uint32_t, uint32_t> ParseHtMcsSet( |
| const std::vector<uint8_t>& ht_mcs_set); |
| uint32_t ParseMcsMap(uint16_t mcs_map); |
| void ParseVhtCapAttribute(const NL80211NestedAttr& band, |
| BandInfo* out_band_info); |
| void ParseHeCapPhyAttribute(const NL80211NestedAttr& attribute, |
| BandInfo* out_band_info); |
| void ParseEhtCapPhyAttribute(const NL80211NestedAttr& attribute, |
| BandInfo* out_band_info); |
| |
| bool ParseScanCapabilities(const NL80211Packet* const packet, |
| ScanCapabilities* out_scan_capabilities); |
| |
| bool MergePacketsForSplitWiphyDump( |
| const std::vector<std::unique_ptr<const NL80211Packet>>& split_dump_info, |
| std::vector<NL80211Packet>* packet_per_wiphy); |
| void handleBandFreqAttributes(const NL80211NestedAttr& freqs_attr, |
| BandInfo* out_band_info); |
| |
| NetlinkManager* netlink_manager_; |
| |
| DISALLOW_COPY_AND_ASSIGN(NetlinkUtils); |
| }; |
| |
| } // namespace wificond |
| } // namespace android |
| |
| #endif // WIFICOND_NET_NETLINK_UTILS_H_ |