/*
* 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 <string>
#include <vector>
#include <android-base/macros.h>
#include "wificond/net/kernel-header-latest/nl80211.h"
#include "wificond/net/netlink_manager.h"
namespace android {
namespace wificond {
struct InterfaceInfo {
InterfaceInfo() = default;
InterfaceInfo(uint32_t index_,
const std::string name_,
const std::vector<uint8_t> mac_address_)
: index(index_),
name(name_),
mac_address(mac_address_) {}
// Index of this interface.
uint32_t index;
// Name of this interface.
std::string name;
// MAC address of this interface.
std::vector<uint8_t> mac_address;
};
struct BandInfo {
BandInfo() = default;
BandInfo(std::vector<uint32_t>& band_2g_,
std::vector<uint32_t>& band_5g_,
std::vector<uint32_t>& band_dfs_)
: band_2g(band_2g_),
band_5g(band_5g_),
band_dfs(band_dfs_) {}
// 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;
};
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) {}
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;
// 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_)
: station_tx_packets(station_tx_packets_),
station_tx_failed(station_tx_failed_),
station_tx_bitrate(station_tx_bitrate_),
current_rssi(current_rssi_) {}
// 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;
// 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);
// 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::vector<uint8_t>& 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);
// 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);
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);
NetlinkManager* netlink_manager_;
DISALLOW_COPY_AND_ASSIGN(NetlinkUtils);
};
} // namespace wificond
} // namespace android
#endif // WIFICOND_NET_NETLINK_UTILS_H_