|
7 | 7 | #include "ddlog.h" |
8 | 8 |
|
9 | 9 | #include "nl_addr.h" |
| 10 | +#include "nl_hwaddr.h" |
10 | 11 | #include "nl_link.h" |
11 | 12 | #include "wireless.h" |
12 | | -#include "nl_hwaddr.h" |
13 | 13 |
|
14 | 14 | #include <QProcess> |
| 15 | +#include <QRegularExpression> |
| 16 | +#include <QRegularExpressionMatch> |
15 | 17 |
|
16 | | -#include <netlink/route/link.h> |
17 | | -#include <netlink/addr.h> |
18 | 18 | #include <linux/sockios.h> |
19 | | -#include<unistd.h> |
20 | | -#include<sys/ioctl.h> |
| 19 | +#include <netlink/addr.h> |
| 20 | +#include <netlink/route/link.h> |
| 21 | +#include <sys/ioctl.h> |
| 22 | +#include <unistd.h> |
21 | 23 |
|
22 | 24 | using namespace DDLog; |
23 | 25 |
|
24 | 26 | namespace core { |
25 | 27 | namespace system { |
26 | 28 |
|
27 | | -NetifInfo::NetifInfo() |
28 | | - : d(new NetifInfoPrivate()) |
29 | | -{ |
30 | | - qCDebug(app) << "NetifInfo constructor"; |
| 29 | +NetifInfo::NetifInfo() : d(new NetifInfoPrivate()) { |
| 30 | + qCDebug(app) << "NetifInfo constructor"; |
31 | 31 | } |
32 | | -NetifInfo::NetifInfo(const NetifInfo &other) |
33 | | - : d(other.d) |
34 | | -{ |
35 | | - qCDebug(app) << "NetifInfo copy constructor"; |
| 32 | +NetifInfo::NetifInfo(const NetifInfo &other) : d(other.d) { |
| 33 | + qCDebug(app) << "NetifInfo copy constructor"; |
36 | 34 | } |
37 | | -NetifInfo &NetifInfo::operator=(const NetifInfo &rhs) |
38 | | -{ |
39 | | - qCDebug(app) << "NetifInfo assignment operator"; |
40 | | - if (this == &rhs) |
41 | | - return *this; |
42 | | - |
43 | | - d = rhs.d; |
| 35 | +NetifInfo &NetifInfo::operator=(const NetifInfo &rhs) { |
| 36 | + qCDebug(app) << "NetifInfo assignment operator"; |
| 37 | + if (this == &rhs) |
44 | 38 | return *this; |
| 39 | + |
| 40 | + d = rhs.d; |
| 41 | + return *this; |
45 | 42 | } |
46 | | -NetifInfo::~NetifInfo() |
47 | | -{ |
48 | | - // qCDebug(app) << "NetifInfo destructor"; |
| 43 | +NetifInfo::~NetifInfo() { |
| 44 | + // qCDebug(app) << "NetifInfo destructor"; |
49 | 45 | } |
50 | 46 |
|
| 47 | +void NetifInfo::set_recv_bps(qreal recv_bps) { d->recv_bps = recv_bps; } |
51 | 48 |
|
52 | | -void NetifInfo::set_recv_bps(qreal recv_bps) |
53 | | -{ |
54 | | - d->recv_bps = recv_bps; |
55 | | -} |
| 49 | +void NetifInfo::set_sent_bps(qreal sent_bps) { d->sent_bps = sent_bps; } |
56 | 50 |
|
57 | | -void NetifInfo::set_sent_bps(qreal sent_bps) |
58 | | -{ |
59 | | - d->sent_bps = sent_bps; |
| 51 | +void NetifInfo::updateHWAddr(const QByteArray ifname) { |
| 52 | + qCDebug(app) << "Updating HW address info for" << ifname; |
| 53 | + NLHWAddr nl_hwaddr(ifname); |
| 54 | + d->conn_type = nl_hwaddr.conn_type(); |
| 55 | + qCDebug(app) << "Connection type for" << ifname << "is" << d->conn_type; |
60 | 56 | } |
61 | 57 |
|
62 | | -void NetifInfo::updateHWAddr(const QByteArray ifname) |
63 | | -{ |
64 | | - qCDebug(app) << "Updating HW address info for" << ifname; |
65 | | - NLHWAddr nl_hwaddr(ifname); |
66 | | - d->conn_type = nl_hwaddr.conn_type(); |
67 | | - qCDebug(app) << "Connection type for" << ifname << "is" << d->conn_type; |
| 58 | +void NetifInfo::updateLinkInfo(const NLLink *link) { |
| 59 | + if (!link) { |
| 60 | + qCWarning(app) << "updateLinkInfo called with null link"; |
| 61 | + return; |
| 62 | + } |
| 63 | + |
| 64 | + qCDebug(app) << "Updating link info for" << link->ifname(); |
| 65 | + |
| 66 | + d->index = link->ifindex(); |
| 67 | + d->ifname = link->ifname(); |
| 68 | + d->alias = link->alias(); |
| 69 | + |
| 70 | + d->mtu = link->mtu(); |
| 71 | + d->flags = link->flags(); |
| 72 | + d->arp_type = link->arp_type(); |
| 73 | + d->txqlen = link->txqlen(); |
| 74 | + d->carrier_changes = link->carrier_changes(); |
| 75 | + d->carrier = link->carrier(); |
| 76 | + d->oper_stat = link->oper_stat(); |
| 77 | + d->link_mode = link->link_mode(); |
| 78 | + d->hw_addr = link->addr(); |
| 79 | + d->hw_bcast = link->bcast(); |
| 80 | + |
| 81 | + // ====link params==== |
| 82 | + |
| 83 | + QByteArray conn_type; |
| 84 | + QString brand; |
| 85 | + |
| 86 | + // ====stats==== |
| 87 | + |
| 88 | + d->rx_packets = link->rx_packets(); |
| 89 | + d->rx_bytes = link->rx_bytes(); |
| 90 | + d->rx_errors = link->rx_errors(); |
| 91 | + d->rx_dropped = link->rx_dropped(); |
| 92 | + d->rx_fifo = link->rx_fifo(); |
| 93 | + d->rx_frame = link->rx_frame(); |
| 94 | + |
| 95 | + d->tx_packets = link->tx_packets(); |
| 96 | + d->tx_bytes = link->tx_bytes(); |
| 97 | + d->tx_errors = link->tx_errors(); |
| 98 | + d->tx_dropped = link->tx_dropped(); |
| 99 | + d->tx_fifo = link->tx_fifo(); |
| 100 | + d->tx_carrier = link->tx_carrier(); |
| 101 | + d->collisions = link->collisions(); |
| 102 | + |
| 103 | + this->updateWirelessInfo(); |
| 104 | + this->updateBrandInfo(); |
| 105 | + this->updateHWAddr(d->ifname); |
| 106 | + qCDebug(app) << "Finished updating link info for" << d->ifname; |
68 | 107 | } |
69 | 108 |
|
70 | | -void NetifInfo::updateLinkInfo(const NLLink *link) |
71 | | -{ |
72 | | - if (!link) { |
73 | | - qCWarning(app) << "updateLinkInfo called with null link"; |
74 | | - return; |
75 | | - } |
76 | | - |
77 | | - qCDebug(app) << "Updating link info for" << link->ifname(); |
78 | | - |
79 | | - d->index = link->ifindex(); |
80 | | - d->ifname = link->ifname(); |
81 | | - d->alias = link->alias(); |
82 | | - |
83 | | - d->mtu = link->mtu(); |
84 | | - d->flags = link->flags(); |
85 | | - d->arp_type = link->arp_type(); |
86 | | - d->txqlen = link->txqlen(); |
87 | | - d->carrier_changes = link->carrier_changes(); |
88 | | - d->carrier = link->carrier(); |
89 | | - d->oper_stat = link->oper_stat(); |
90 | | - d->link_mode = link->link_mode(); |
91 | | - d->hw_addr = link->addr(); |
92 | | - d->hw_bcast = link->bcast(); |
93 | | - |
94 | | - // ====link params==== |
95 | | - |
96 | | - QByteArray conn_type; |
97 | | - QString brand; |
98 | | - |
99 | | - // ====stats==== |
100 | | - |
101 | | - d->rx_packets = link->rx_packets(); |
102 | | - d->rx_bytes = link->rx_bytes(); |
103 | | - d->rx_errors = link->rx_errors(); |
104 | | - d->rx_dropped = link->rx_dropped(); |
105 | | - d->rx_fifo = link->rx_fifo(); |
106 | | - d->rx_frame = link->rx_frame(); |
107 | | - |
108 | | - d->tx_packets = link->tx_packets(); |
109 | | - d->tx_bytes = link->tx_bytes(); |
110 | | - d->tx_errors = link->tx_errors(); |
111 | | - d->tx_dropped = link->tx_dropped(); |
112 | | - d->tx_fifo = link->tx_fifo(); |
113 | | - d->tx_carrier = link->tx_carrier(); |
114 | | - d->collisions = link->collisions(); |
115 | | - |
116 | | - this->updateWirelessInfo(); |
117 | | - this->updateBrandInfo(); |
118 | | - this->updateHWAddr(d->ifname); |
119 | | - qCDebug(app) << "Finished updating link info for" << d->ifname; |
| 109 | +void NetifInfo::updateWirelessInfo() { |
| 110 | + qCDebug(app) << "Updating wireless info for" << d->ifname; |
| 111 | + wireless wireless1(d->ifname); |
| 112 | + if (wireless1.is_wireless()) { |
| 113 | + qCDebug(app) << d->ifname << "is a wireless device"; |
| 114 | + d->isWireless = true; |
| 115 | + d->iw_info->essid = wireless1.essid(); |
| 116 | + d->iw_info->qual.qual = wireless1.link_quality(); |
| 117 | + d->iw_info->qual.level = wireless1.signal_levle(); |
| 118 | + d->iw_info->qual.noise = wireless1.noise_level(); |
| 119 | + // 速率 |
| 120 | + auto speed = getWirelessSpeed(d->ifname); |
| 121 | + if (speed >= 0) |
| 122 | + d->speed = static_cast<uint>(speed); |
| 123 | + } else { |
| 124 | + qCDebug(app) << d->ifname << "is not a wireless device"; |
| 125 | + d->isWireless = false; |
| 126 | + } |
120 | 127 | } |
121 | 128 |
|
122 | | -void NetifInfo::updateWirelessInfo() |
123 | | -{ |
124 | | - qCDebug(app) << "Updating wireless info for" << d->ifname; |
125 | | - wireless wireless1(d->ifname); |
126 | | - if (wireless1.is_wireless()) { |
127 | | - qCDebug(app) << d->ifname << "is a wireless device"; |
128 | | - d->isWireless = true; |
129 | | - d->iw_info->essid = wireless1.essid(); |
130 | | - d->iw_info->qual.qual = wireless1.link_quality(); |
131 | | - d->iw_info->qual.level = wireless1.signal_levle(); |
132 | | - d->iw_info->qual.noise = wireless1.noise_level(); |
133 | | - // 速率 |
134 | | - //无线网速率ioctl没有提供相关接口,目前采用调用iwlist命令的方式获取 #bug 111694 |
135 | | - QProcess process; |
136 | | - QString cmd = QString("iwlist ") + d.data()->ifname + QString(" rate"); |
137 | | - qCDebug(app) << "Executing command:" << cmd; |
138 | | - process.start(cmd); |
139 | | - process.waitForFinished(-1); |
140 | | - //获取输出 |
141 | | - QString data = process.readAllStandardOutput(); |
142 | | - qCDebug(app) << "iwlist output:" << data.trimmed(); |
143 | | - QStringList datalist = data.trimmed().split(":"); |
144 | | - if (datalist.size() > 0) { |
145 | | - QString speedString = datalist[datalist.size() - 1]; |
146 | | - float fspeed = 0; |
147 | | - QStringList list = speedString.split(" "); |
148 | | - if (list.size() > 0) { |
149 | | - fspeed = list[0].toFloat(); |
150 | | - } |
151 | | - d->speed = static_cast<uint>(fspeed); |
152 | | - qCDebug(app) << "Parsed wireless speed:" << d->speed << "Mb/s"; |
153 | | - } |
154 | | - } else { |
155 | | - qCDebug(app) << d->ifname << "is not a wireless device"; |
156 | | - d->isWireless = false; |
157 | | - } |
| 129 | +void NetifInfo::updateBrandInfo() { |
| 130 | + qCDebug(app) << "Updating brand info for" << d->ifname; |
| 131 | + struct ifreq ifr; |
| 132 | + struct ethtool_cmd ecmd; |
| 133 | + |
| 134 | + ecmd.cmd = 0x00000001; |
| 135 | + memset(&ifr, 0, sizeof(ifr)); |
| 136 | + strcpy(ifr.ifr_name, d->ifname); |
| 137 | + |
| 138 | + ifr.ifr_data = reinterpret_cast<caddr_t>(&ecmd); |
| 139 | + int fd = socket(PF_INET, SOCK_DGRAM, 0); |
| 140 | + if (ioctl(fd, SIOCETHTOOL, &ifr) == 0) { |
| 141 | + d->speed = ecmd.speed; |
| 142 | + qCDebug(app) << "Got speed via ioctl:" << d->speed; |
| 143 | + } |
| 144 | + close(fd); |
158 | 145 | } |
159 | 146 |
|
160 | | -void NetifInfo::updateBrandInfo() |
161 | | -{ |
162 | | - qCDebug(app) << "Updating brand info for" << d->ifname; |
163 | | - struct ifreq ifr; |
164 | | - struct ethtool_cmd ecmd; |
165 | | - |
166 | | - ecmd.cmd = 0x00000001; |
167 | | - memset(&ifr, 0, sizeof(ifr)); |
168 | | - strcpy(ifr.ifr_name, d->ifname); |
169 | | - |
170 | | - ifr.ifr_data = reinterpret_cast<caddr_t>(&ecmd); |
171 | | - int fd = socket(PF_INET, SOCK_DGRAM, 0); |
172 | | - if (ioctl(fd, SIOCETHTOOL, &ifr) == 0) { |
173 | | - d->speed = ecmd.speed; |
174 | | - qCDebug(app) << "Got speed via ioctl:" << d->speed; |
175 | | - } |
176 | | - close(fd); |
| 147 | +double NetifInfo::getWirelessSpeed(const QString &interface) { |
| 148 | + QProcess process; |
| 149 | + process.start("iw", QStringList() << "dev" << interface << "link"); |
| 150 | + process.waitForFinished(); |
| 151 | + QString output = process.readAllStandardOutput(); |
| 152 | + |
| 153 | + // 解析发送速率,实测发现控制中心显示的速率是 tx bitrate,所以这里只捕获 tx |
| 154 | + // bitrate |
| 155 | + QRegularExpression txRegex("tx bitrate:\\s+(\\d+\\.?\\d*)\\s+(\\w+)"); |
| 156 | + QRegularExpressionMatch txMatch = txRegex.match(output); |
| 157 | + |
| 158 | + if (txMatch.hasMatch()) { |
| 159 | + double rate = txMatch.captured(1).toDouble(); |
| 160 | + return static_cast<long>(rate); |
| 161 | + } |
| 162 | + |
| 163 | + return -1; // 表示无法获取速率 |
177 | 164 | } |
178 | 165 |
|
179 | 166 | } // namespace system |
|
0 commit comments