PR #4190 (merged as 93d85a0) reworked getNetworkState() so the rfkill
"disabled" state is evaluated whenever the module has no carrier. Because
the module always watches an RFKILL_TYPE_WLAN switch, a wired ethernet
module whose cable is unplugged (carrier lost) would return "disabled"
instead of "disconnected" whenever the system's WLAN radio happened to be
rfkill-blocked. With no format-disabled configured, that state falls back
to plain "format", so the interface kept looking connected after unplug.
rfkill only concerns wireless radios, so only honor it when there is no
interface at all or the current interface is actually wireless (detected
via /sys/class/net/<if>/phy80211 or /wireless). A wired interface that
lost its carrier now correctly reports "disconnected", while wifi rfkill
display from #4190 is preserved.
Fixes #4364.
112 lines
2.9 KiB
C++
112 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <arpa/inet.h>
|
|
#include <fmt/format.h>
|
|
#include <linux/nl80211.h>
|
|
#include <netlink/genl/ctrl.h>
|
|
#include <netlink/genl/genl.h>
|
|
#include <netlink/netlink.h>
|
|
#include <sys/epoll.h>
|
|
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
#include "ALabel.hpp"
|
|
#include "util/sleeper_thread.hpp"
|
|
#ifdef WANT_RFKILL
|
|
#include "util/rfkill.hpp"
|
|
#endif
|
|
|
|
#define ETH_ALEN 6
|
|
|
|
enum ip_addr_pref : uint8_t { IPV4, IPV6, IPV4_6 };
|
|
|
|
namespace waybar::modules {
|
|
|
|
class Network : public ALabel {
|
|
public:
|
|
Network(const std::string&, const Json::Value&);
|
|
virtual ~Network();
|
|
auto update() -> void override;
|
|
|
|
private:
|
|
static const uint8_t MAX_RETRY{5};
|
|
static const uint8_t EPOLL_MAX{200};
|
|
|
|
static int handleEvents(struct nl_msg*, void*);
|
|
static int handleEventsDone(struct nl_msg*, void*);
|
|
static int handleScan(struct nl_msg*, void*);
|
|
static int handleStationGet(struct nl_msg *msg, void *data);
|
|
|
|
void askForStateDump(void);
|
|
|
|
void worker();
|
|
void createInfoSocket();
|
|
void createEventSocket();
|
|
void parseEssid(struct nlattr**);
|
|
void parseSignal(struct nlattr**);
|
|
void parseFreq(struct nlattr**);
|
|
void parseBssid(struct nlattr**);
|
|
bool associatedOrJoined(struct nlattr**);
|
|
bool matchInterface(const std::string& ifname, const std::vector<std::string>& altnames,
|
|
std::string& matched) const;
|
|
auto getInfo() -> void;
|
|
bool isWireless() const;
|
|
const std::string getNetworkState() const;
|
|
void clearIface();
|
|
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
|
uint32_t readLinkSpeed() const;
|
|
|
|
int ifid_{-1};
|
|
ip_addr_pref addr_pref_{ip_addr_pref::IPV4};
|
|
struct sockaddr_nl nladdr_{0};
|
|
struct nl_sock* sock_{nullptr};
|
|
struct nl_sock* ev_sock_{nullptr};
|
|
struct nl_sock* station_sock_{nullptr};
|
|
int efd_{-1};
|
|
int ev_fd_{-1};
|
|
int nl80211_id_{-1};
|
|
std::mutex mutex_;
|
|
|
|
bool want_route_dump_{false};
|
|
bool want_link_dump_{false};
|
|
bool want_addr_dump_{false};
|
|
bool dump_in_progress_{false};
|
|
bool is_p2p_{false};
|
|
|
|
unsigned long long bandwidth_down_total_{0};
|
|
unsigned long long bandwidth_up_total_{0};
|
|
unsigned long long bandwidth_down_prev_{0};
|
|
unsigned long long bandwidth_up_prev_{0};
|
|
std::chrono::steady_clock::time_point bandwidth_last_sample_time_;
|
|
|
|
std::string state_;
|
|
std::string essid_;
|
|
std::string bssid_;
|
|
bool carrier_{false};
|
|
std::string ifname_;
|
|
std::string ipaddr_;
|
|
std::string ipaddr6_;
|
|
std::string gwaddr_;
|
|
std::string netmask_;
|
|
std::string netmask6_;
|
|
int cidr_{0};
|
|
int cidr6_{0};
|
|
int32_t signal_strength_dbm_;
|
|
uint8_t signal_strength_;
|
|
std::string signal_strength_app_;
|
|
uint32_t route_priority;
|
|
uint32_t link_speed_{0};
|
|
|
|
util::SleeperThread thread_;
|
|
util::SleeperThread thread_timer_;
|
|
#ifdef WANT_RFKILL
|
|
util::Rfkill rfkill_{RFKILL_TYPE_WLAN};
|
|
#endif
|
|
float frequency_{0};
|
|
uint32_t tx_bitrate_{0};
|
|
uint32_t rx_bitrate_{0};
|
|
};
|
|
|
|
} // namespace waybar::modules
|