You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
342 lines
13 KiB
342 lines
13 KiB
/*
|
|
* 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_160_mhz_supported(false),
|
|
is_80p80_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 160Mhz channel width
|
|
bool is_160_mhz_supported;
|
|
// support for 80+80Mhz channel width
|
|
bool is_80p80_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);
|
|
|
|
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_
|