1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtSystems module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL21$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see http://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at http://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 or version 3 as published by the Free |
20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and |
21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the |
22 | ** following information to ensure the GNU Lesser General Public License |
23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and |
24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
25 | ** |
26 | ** As a special exception, The Qt Company gives you certain additional |
27 | ** rights. These rights are described in The Qt Company LGPL Exception |
28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
29 | ** |
30 | ** $QT_END_LICENSE$ |
31 | ** |
32 | ****************************************************************************/ |
33 | |
34 | #include "qnetworkinfo_linux_p.h" |
35 | |
36 | #if !defined(QT_NO_OFONO) |
37 | #include "qofonowrapper_p.h" |
38 | #endif |
39 | |
40 | #include <QtCore/qdir.h> |
41 | #include <QtCore/qfile.h> |
42 | #include <QtCore/qmetaobject.h> |
43 | #include <QtCore/qtextstream.h> |
44 | #include <QtCore/qtimer.h> |
45 | #if !defined(QT_NO_BLUEZ) |
46 | #include <bluetooth/bluetooth.h> |
47 | #include <bluetooth/hci.h> |
48 | #include <bluetooth/hci_lib.h> |
49 | #endif // QT_NO_BLUEZ |
50 | |
51 | #if !defined(QT_NO_UDEV) |
52 | #include <QtCore/qsocketnotifier.h> |
53 | #include <libudev.h> |
54 | #endif // QT_NO_UDEV |
55 | |
56 | #include <math.h> |
57 | #include <sys/ioctl.h> |
58 | #include <sys/types.h> |
59 | #include <sys/socket.h> |
60 | #include <linux/wireless.h> |
61 | #include <unistd.h> |
62 | |
63 | QT_BEGIN_NAMESPACE |
64 | |
65 | Q_GLOBAL_STATIC_WITH_ARGS(const QString, NETWORK_SYSFS_PATH, (QLatin1String("/sys/class/net/" ))) |
66 | |
67 | Q_GLOBAL_STATIC_WITH_ARGS(const QStringList, WLAN_MASK, (QStringList() << QLatin1String("wlan*" ) << QLatin1String("wlp*" ))) |
68 | Q_GLOBAL_STATIC_WITH_ARGS(const QStringList, ETHERNET_MASK, (QStringList() << QLatin1String("eth*" ) << QLatin1String("usb*" ) << QLatin1String("enp*" ))) |
69 | |
70 | QNetworkInfoPrivate::QNetworkInfoPrivate(QNetworkInfo *parent) |
71 | : QObject(parent) |
72 | , q_ptr(parent) |
73 | , watchCurrentNetworkMode(false) |
74 | , watchNetworkInterfaceCount(false) |
75 | , watchNetworkSignalStrength(false) |
76 | , watchNetworkStatus(false) |
77 | , watchNetworkName(false) |
78 | , timer(0) |
79 | #if !defined(QT_NO_OFONO) |
80 | , ofonoWrapper(0) |
81 | #endif |
82 | #if !defined(QT_NO_UDEV) |
83 | , udevNotifier(0) |
84 | , udevHandle(0) |
85 | , udevMonitor(0) |
86 | #endif // QT_NO_UDEV |
87 | { |
88 | } |
89 | |
90 | QNetworkInfoPrivate::~QNetworkInfoPrivate() |
91 | { |
92 | #if !defined(QT_NO_UDEV) |
93 | if (udevMonitor) |
94 | udev_monitor_unref(udevMonitor); |
95 | |
96 | if (udevHandle) |
97 | udev_unref(udevHandle); |
98 | #endif // QT_NO_UDEV |
99 | } |
100 | |
101 | int QNetworkInfoPrivate::networkInterfaceCount(QNetworkInfo::NetworkMode mode) |
102 | { |
103 | if (watchNetworkInterfaceCount && (mode == QNetworkInfo::WlanMode |
104 | || mode == QNetworkInfo::EthernetMode |
105 | || mode == QNetworkInfo::BluetoothMode)) { |
106 | return networkInterfaceCounts.value(akey: mode); |
107 | } else |
108 | return getNetworkInterfaceCount(mode); |
109 | } |
110 | |
111 | int QNetworkInfoPrivate::networkSignalStrength(QNetworkInfo::NetworkMode mode, int interface) |
112 | { |
113 | if (watchNetworkSignalStrength && (mode == QNetworkInfo::WlanMode |
114 | || mode == QNetworkInfo::EthernetMode |
115 | || mode == QNetworkInfo::BluetoothMode)) { |
116 | return networkSignalStrengths.value(akey: QPair<QNetworkInfo::NetworkMode, int>(mode, interface)); |
117 | } else |
118 | return getNetworkSignalStrength(mode, interface); |
119 | } |
120 | |
121 | QNetworkInfo::CellDataTechnology QNetworkInfoPrivate::currentCellDataTechnology(int interface) |
122 | { |
123 | #if !defined(QT_NO_OFONO) |
124 | if (QOfonoWrapper::isOfonoAvailable()) { |
125 | if (!ofonoWrapper) |
126 | ofonoWrapper = new QOfonoWrapper(this); |
127 | QStringList modems = ofonoWrapper->allModems(); |
128 | if (interface < modems.size()) { |
129 | QString modem = ofonoWrapper->allModems().at(interface); |
130 | if (!modem.isEmpty()) |
131 | return ofonoWrapper->currentCellDataTechnology(modem); |
132 | } |
133 | } |
134 | #else |
135 | Q_UNUSED(interface) |
136 | #endif |
137 | return QNetworkInfo::UnknownDataTechnology; |
138 | } |
139 | |
140 | QNetworkInfo::NetworkMode QNetworkInfoPrivate::currentNetworkMode() |
141 | { |
142 | if (watchCurrentNetworkMode) |
143 | return currentMode; |
144 | else |
145 | return getCurrentNetworkMode(); |
146 | } |
147 | |
148 | QNetworkInfo::NetworkStatus QNetworkInfoPrivate::networkStatus(QNetworkInfo::NetworkMode mode, int interface) |
149 | { |
150 | if (watchNetworkStatus && (mode == QNetworkInfo::WlanMode |
151 | || mode == QNetworkInfo::EthernetMode |
152 | || mode == QNetworkInfo::BluetoothMode)) { |
153 | return networkStatuses.value(akey: QPair<QNetworkInfo::NetworkMode, int>(mode, interface)); |
154 | } else |
155 | return getNetworkStatus(mode, interface); |
156 | } |
157 | |
158 | #ifndef QT_NO_NETWORKINTERFACE |
159 | QNetworkInterface QNetworkInfoPrivate::interfaceForMode(QNetworkInfo::NetworkMode mode, int interface) |
160 | { |
161 | switch (mode) { |
162 | case QNetworkInfo::WlanMode: { |
163 | QStringList dirs = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *WLAN_MASK()); |
164 | if (interface < dirs.size()) { |
165 | QNetworkInterface networkInterface = QNetworkInterface::interfaceFromName(name: dirs.at(i: interface)); |
166 | if (networkInterface.isValid()) |
167 | return networkInterface; |
168 | } |
169 | break; |
170 | } |
171 | |
172 | case QNetworkInfo::EthernetMode: { |
173 | QStringList dirs = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *ETHERNET_MASK()); |
174 | if (interface < dirs.size()) { |
175 | QNetworkInterface networkInterface = QNetworkInterface::interfaceFromName(name: dirs.at(i: interface)); |
176 | if (networkInterface.isValid()) |
177 | return networkInterface; |
178 | } |
179 | break; |
180 | } |
181 | |
182 | // case QNetworkInfo::BluetoothMode: |
183 | // case QNetworkInfo::GsmMode: |
184 | // case QNetworkInfo::CdmaMode: |
185 | // case QNetworkInfo::WcdmaMode: |
186 | // case QNetworkInfo::WimaxMode: |
187 | // case QNetworkInfo::LteMode: |
188 | // case QNetworkInfo::TdscdmaMode: |
189 | default: |
190 | break; |
191 | }; |
192 | |
193 | return QNetworkInterface(); |
194 | } |
195 | #endif // QT_NO_NETWORKINTERFACE |
196 | |
197 | QString QNetworkInfoPrivate::cellId(int interface) |
198 | { |
199 | #if !defined(QT_NO_OFONO) |
200 | if (QOfonoWrapper::isOfonoAvailable()) { |
201 | if (!ofonoWrapper) |
202 | ofonoWrapper = new QOfonoWrapper(this); |
203 | QStringList modems = ofonoWrapper->allModems(); |
204 | if (interface < modems.size()) { |
205 | QString modem = ofonoWrapper->allModems().at(interface); |
206 | if (!modem.isEmpty()) |
207 | return ofonoWrapper->cellId(modem); |
208 | } |
209 | } |
210 | #else |
211 | Q_UNUSED(interface) |
212 | #endif |
213 | return QString(); |
214 | } |
215 | |
216 | QString QNetworkInfoPrivate::currentMobileCountryCode(int interface) |
217 | { |
218 | #if !defined(QT_NO_OFONO) |
219 | if (QOfonoWrapper::isOfonoAvailable()) { |
220 | if (!ofonoWrapper) |
221 | ofonoWrapper = new QOfonoWrapper(this); |
222 | QStringList modems = ofonoWrapper->allModems(); |
223 | if (interface < modems.size()) { |
224 | QString modem = ofonoWrapper->allModems().at(interface); |
225 | if (!modem.isEmpty()) |
226 | return ofonoWrapper->currentMcc(modem); |
227 | } |
228 | } |
229 | #else |
230 | Q_UNUSED(interface) |
231 | #endif |
232 | return QString(); |
233 | } |
234 | |
235 | QString QNetworkInfoPrivate::currentMobileNetworkCode(int interface) |
236 | { |
237 | #if !defined(QT_NO_OFONO) |
238 | if (QOfonoWrapper::isOfonoAvailable()) { |
239 | if (!ofonoWrapper) |
240 | ofonoWrapper = new QOfonoWrapper(this); |
241 | QStringList modems = ofonoWrapper->allModems(); |
242 | if (interface < modems.size()) { |
243 | QString modem = ofonoWrapper->allModems().at(interface); |
244 | if (!modem.isEmpty()) |
245 | return ofonoWrapper->currentMnc(modem); |
246 | } |
247 | } |
248 | #else |
249 | Q_UNUSED(interface) |
250 | #endif |
251 | return QString(); |
252 | } |
253 | |
254 | QString QNetworkInfoPrivate::homeMobileCountryCode(int interface) |
255 | { |
256 | #if !defined(QT_NO_OFONO) |
257 | if (QOfonoWrapper::isOfonoAvailable()) { |
258 | if (!ofonoWrapper) |
259 | ofonoWrapper = new QOfonoWrapper(this); |
260 | QStringList modems = ofonoWrapper->allModems(); |
261 | if (interface < modems.size()) { |
262 | QString modem = ofonoWrapper->allModems().at(interface); |
263 | if (!modem.isEmpty()) |
264 | return ofonoWrapper->homeMcc(modem); |
265 | } |
266 | } |
267 | #else |
268 | Q_UNUSED(interface) |
269 | #endif |
270 | return QString(); |
271 | } |
272 | |
273 | QString QNetworkInfoPrivate::homeMobileNetworkCode(int interface) |
274 | { |
275 | #if !defined(QT_NO_OFONO) |
276 | if (QOfonoWrapper::isOfonoAvailable()) { |
277 | if (!ofonoWrapper) |
278 | ofonoWrapper = new QOfonoWrapper(this); |
279 | QStringList modems = ofonoWrapper->allModems(); |
280 | if (interface < modems.size()) { |
281 | QString modem = ofonoWrapper->allModems().at(interface); |
282 | if (!modem.isEmpty()) |
283 | return ofonoWrapper->homeMnc(modem); |
284 | } |
285 | } |
286 | #else |
287 | Q_UNUSED(interface) |
288 | #endif |
289 | return QString(); |
290 | } |
291 | |
292 | QString QNetworkInfoPrivate::imsi(int interface) |
293 | { |
294 | #if !defined(QT_NO_OFONO) |
295 | if (QOfonoWrapper::isOfonoAvailable()) { |
296 | if (!ofonoWrapper) |
297 | ofonoWrapper = new QOfonoWrapper(this); |
298 | QStringList modems = ofonoWrapper->allModems(); |
299 | if (interface < modems.size()) { |
300 | QString modem = ofonoWrapper->allModems().at(interface); |
301 | if (!modem.isEmpty()) |
302 | return ofonoWrapper->imsi(modem); |
303 | } |
304 | } |
305 | #else |
306 | Q_UNUSED(interface) |
307 | #endif |
308 | return QString(); |
309 | } |
310 | |
311 | QString QNetworkInfoPrivate::locationAreaCode(int interface) |
312 | { |
313 | #if !defined(QT_NO_OFONO) |
314 | if (QOfonoWrapper::isOfonoAvailable()) { |
315 | if (!ofonoWrapper) |
316 | ofonoWrapper = new QOfonoWrapper(this); |
317 | QStringList modems = ofonoWrapper->allModems(); |
318 | if (interface < modems.size()) { |
319 | QString modem = ofonoWrapper->allModems().at(interface); |
320 | if (!modem.isEmpty()) |
321 | return ofonoWrapper->lac(modem); |
322 | } |
323 | } |
324 | #else |
325 | Q_UNUSED(interface) |
326 | #endif |
327 | return QString(); |
328 | } |
329 | |
330 | QString QNetworkInfoPrivate::macAddress(QNetworkInfo::NetworkMode mode, int interface) |
331 | { |
332 | switch (mode) { |
333 | case QNetworkInfo::WlanMode: { |
334 | QStringList dirs = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *WLAN_MASK()); |
335 | if (interface < dirs.size()) { |
336 | QFile carrier(*NETWORK_SYSFS_PATH() + dirs.at(i: interface) + QString(QStringLiteral("/address" ))); |
337 | if (carrier.open(flags: QIODevice::ReadOnly)) |
338 | return QString::fromLatin1(str: carrier.readAll().simplified().data()); |
339 | } |
340 | break; |
341 | } |
342 | |
343 | case QNetworkInfo::EthernetMode: { |
344 | QStringList dirs = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *ETHERNET_MASK()); |
345 | if (interface < dirs.size()) { |
346 | QFile carrier(*NETWORK_SYSFS_PATH() + dirs.at(i: interface) + QString(QStringLiteral("/address" ))); |
347 | if (carrier.open(flags: QIODevice::ReadOnly)) |
348 | return QString::fromLatin1(str: carrier.readAll().simplified().data()); |
349 | } |
350 | break; |
351 | } |
352 | |
353 | case QNetworkInfo::BluetoothMode: { |
354 | #if !defined(QT_NO_BLUEZ) |
355 | int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); |
356 | if (ctl < 0) |
357 | break; |
358 | struct hci_dev_list_req *deviceList = (struct hci_dev_list_req *)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); |
359 | deviceList->dev_num = HCI_MAX_DEV; |
360 | QString macAddress; |
361 | if (ioctl(fd: ctl, HCIGETDEVLIST, deviceList) == 0) { |
362 | int count = deviceList->dev_num; |
363 | if (interface < count) { |
364 | struct hci_dev_info deviceInfo; |
365 | deviceInfo.dev_id = (deviceList->dev_req + interface)->dev_id; |
366 | if (ioctl(fd: ctl, HCIGETDEVINFO, &deviceInfo) == 0) { |
367 | // do not use BDADDR_ANY, fails with gcc 4.6 |
368 | bdaddr_t bdaddr_any = (bdaddr_t) {.b: {0, 0, 0, 0, 0, 0}}; |
369 | if (hci_test_bit(nr: HCI_RAW, addr: &deviceInfo.flags) && !bacmp(ba1: &deviceInfo.bdaddr, ba2: &bdaddr_any)) { |
370 | int hciDevice = hci_open_dev(dev_id: deviceInfo.dev_id); |
371 | hci_read_bd_addr(dd: hciDevice, bdaddr: &deviceInfo.bdaddr, to: 1000); |
372 | hci_close_dev(dd: hciDevice); |
373 | } |
374 | char address[18]; |
375 | ba2str(ba: &deviceInfo.bdaddr, str: address); |
376 | macAddress = QString::fromLatin1(str: address); |
377 | } |
378 | } |
379 | } |
380 | free(ptr: deviceList); |
381 | close(fd: ctl); |
382 | return macAddress; |
383 | #else |
384 | break; |
385 | #endif // QT_NO_BLUEZ |
386 | } |
387 | |
388 | // case QNetworkInfo::GsmMode: |
389 | // case QNetworkInfo::CdmaMode: |
390 | // case QNetworkInfo::WcdmaMode: |
391 | // case QNetworkInfo::WimaxMode: |
392 | // case QNetworkInfo::LteMode: |
393 | // case QNetworkInfo::TdscdmaMode: |
394 | default: |
395 | break; |
396 | }; |
397 | |
398 | return QString(); |
399 | } |
400 | |
401 | QString QNetworkInfoPrivate::networkName(QNetworkInfo::NetworkMode mode, int interface) |
402 | { |
403 | if (watchNetworkName && (mode == QNetworkInfo::WlanMode |
404 | || mode == QNetworkInfo::EthernetMode |
405 | || mode == QNetworkInfo::BluetoothMode)) { |
406 | return networkNames.value(akey: QPair<QNetworkInfo::NetworkMode, int>(mode, interface)); |
407 | } else |
408 | return getNetworkName(mode, interface); |
409 | } |
410 | |
411 | extern QMetaMethod proxyToSourceSignal(const QMetaMethod &, QObject *); |
412 | |
413 | void QNetworkInfoPrivate::connectNotify(const QMetaMethod &signal) |
414 | { |
415 | #if !defined(QT_NO_OFONO) |
416 | if (QOfonoWrapper::isOfonoAvailable()) { |
417 | if (!ofonoWrapper) |
418 | ofonoWrapper = new QOfonoWrapper(this); |
419 | QMetaMethod sourceSignal = proxyToSourceSignal(signal, ofonoWrapper); |
420 | connect(ofonoWrapper, sourceSignal, this, signal, Qt::UniqueConnection); |
421 | } |
422 | #endif |
423 | |
424 | static const QMetaMethod currentNetworkModeChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::currentNetworkModeChanged); |
425 | static const QMetaMethod networkNameChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkNameChanged); |
426 | static const QMetaMethod networkSignalStrengthChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkSignalStrengthChanged); |
427 | static const QMetaMethod networkStatusChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkStatusChanged); |
428 | |
429 | // we always monitor "networkInterfaceCount" , as long as users connect any signals, |
430 | // with update to date network interface counts, we can compute network mode, strength, |
431 | // status, name properties in an efficient way |
432 | if (!watchNetworkInterfaceCount) { |
433 | QList<QNetworkInfo::NetworkMode> modes; |
434 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
435 | networkInterfaceCounts.clear(); |
436 | foreach (QNetworkInfo::NetworkMode mode, modes) |
437 | networkInterfaceCounts[mode] = getNetworkInterfaceCount(mode); |
438 | #if !defined(QT_NO_UDEV) |
439 | if (!udevHandle) { |
440 | udevHandle = udev_new(); |
441 | udevMonitor = udev_monitor_new_from_netlink(udevHandle, "udev" ); |
442 | udev_monitor_filter_add_match_subsystem_devtype(udevMonitor, "net" , NULL); |
443 | udev_monitor_enable_receiving(udevMonitor); |
444 | udevNotifier = new QSocketNotifier(udev_monitor_get_fd(udevMonitor), QSocketNotifier::Read, this); |
445 | connect(udevNotifier, SIGNAL(activated(int)), this, SLOT(onUdevChanged())); |
446 | } |
447 | udevNotifier->setEnabled(true); |
448 | |
449 | #endif // QT_NO_UDEV |
450 | watchNetworkInterfaceCount = true; |
451 | } |
452 | |
453 | if (signal == currentNetworkModeChangedSignal) { |
454 | // we monitor "networkStatus" by default, as long as currentNetworkModeChanged signal |
455 | // is connected, with always up to date network status, current network mode can |
456 | // be fast computed. |
457 | if (!watchNetworkStatus) { |
458 | QList<QNetworkInfo::NetworkMode> modes; |
459 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
460 | networkStatuses.clear(); |
461 | foreach (QNetworkInfo::NetworkMode mode, modes) { |
462 | int count = networkInterfaceCount(mode); |
463 | for (int i = 0; i < count; ++i) |
464 | networkStatuses[QPair<QNetworkInfo::NetworkMode, int>(mode, i)] = getNetworkStatus(mode, interface: i); |
465 | } |
466 | watchNetworkStatus = true; |
467 | } |
468 | currentMode = getCurrentNetworkMode(); |
469 | watchCurrentNetworkMode = true; |
470 | } else if (signal == networkSignalStrengthChangedSignal) { |
471 | QList<QNetworkInfo::NetworkMode> modes; |
472 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
473 | networkSignalStrengths.clear(); |
474 | foreach (QNetworkInfo::NetworkMode mode, modes) { |
475 | int count = networkInterfaceCount(mode); |
476 | for (int i = 0; i < count; ++i) |
477 | networkSignalStrengths[QPair<QNetworkInfo::NetworkMode, int>(mode, i)] = getNetworkSignalStrength(mode, interface: i); |
478 | } |
479 | |
480 | watchNetworkSignalStrength = true; |
481 | } else if (signal == networkStatusChangedSignal) { |
482 | QList<QNetworkInfo::NetworkMode> modes; |
483 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
484 | networkStatuses.clear(); |
485 | foreach (QNetworkInfo::NetworkMode mode, modes) { |
486 | int count = networkInterfaceCount(mode); |
487 | for (int i = 0; i < count; ++i) |
488 | networkStatuses[QPair<QNetworkInfo::NetworkMode, int>(mode, i)] = getNetworkStatus(mode, interface: i); |
489 | } |
490 | |
491 | watchNetworkStatus = true; |
492 | } else if (signal == networkNameChangedSignal) { |
493 | QList<QNetworkInfo::NetworkMode> modes; |
494 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
495 | networkNames.clear(); |
496 | foreach (QNetworkInfo::NetworkMode mode, modes) { |
497 | int count = networkInterfaceCount(mode); |
498 | for (int i = 0; i < count; ++i) |
499 | networkNames[QPair<QNetworkInfo::NetworkMode, int>(mode, i)] = getNetworkName(mode, interface: i); |
500 | } |
501 | |
502 | watchNetworkName = true; |
503 | } else if (signal == currentNetworkModeChangedSignal) { |
504 | currentMode = getCurrentNetworkMode(); |
505 | watchCurrentNetworkMode = true; |
506 | } else { |
507 | return; |
508 | } |
509 | |
510 | if (!timer) { |
511 | timer = new QTimer(this); |
512 | timer->setInterval(2000); |
513 | connect(sender: timer, SIGNAL(timeout()), receiver: this, SLOT(onTimeout())); |
514 | } |
515 | |
516 | if (!timer->isActive()) |
517 | timer->start(); |
518 | } |
519 | |
520 | void QNetworkInfoPrivate::disconnectNotify(const QMetaMethod &signal) |
521 | { |
522 | #if !defined(QT_NO_OFONO) |
523 | if (!QOfonoWrapper::isOfonoAvailable() || !ofonoWrapper) |
524 | return; |
525 | |
526 | { |
527 | QMetaMethod sourceSignal = proxyToSourceSignal(signal, ofonoWrapper); |
528 | disconnect(ofonoWrapper, sourceSignal, this, signal); |
529 | } |
530 | #endif |
531 | |
532 | static const QMetaMethod currentNetworkModeChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::currentNetworkModeChanged); |
533 | static const QMetaMethod networkInterfaceCountChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkInterfaceCountChanged); |
534 | static const QMetaMethod networkNameChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkNameChanged); |
535 | static const QMetaMethod networkSignalStrengthChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkSignalStrengthChanged); |
536 | static const QMetaMethod networkStatusChangedSignal = QMetaMethod::fromSignal(signal: &QNetworkInfoPrivate::networkStatusChanged); |
537 | |
538 | if (signal == networkInterfaceCountChangedSignal |
539 | && !watchNetworkStatus && !watchNetworkName && !watchNetworkSignalStrength ) { |
540 | #if !defined(QT_NO_UDEV) |
541 | udevNotifier->setEnabled(false); |
542 | watchNetworkInterfaceCount = false; |
543 | return; |
544 | #endif // QT_NO_UDEV |
545 | watchNetworkInterfaceCount = false; |
546 | } else if (signal == networkSignalStrengthChangedSignal) { |
547 | watchNetworkSignalStrength = false; |
548 | } else if ((!watchCurrentNetworkMode) && (signal == networkStatusChangedSignal)) { |
549 | watchNetworkStatus = false; |
550 | } else if (signal == networkNameChangedSignal) { |
551 | watchNetworkName = false; |
552 | } else if (signal == currentNetworkModeChangedSignal) { |
553 | watchCurrentNetworkMode = false; |
554 | } else { |
555 | return; |
556 | } |
557 | |
558 | if (!watchNetworkInterfaceCount && !watchNetworkSignalStrength && !watchNetworkStatus && !watchNetworkName && !watchCurrentNetworkMode) |
559 | timer->stop(); |
560 | } |
561 | |
562 | #if !defined(QT_NO_UDEV) |
563 | void QNetworkInfoPrivate::onUdevChanged() |
564 | { |
565 | struct udev_device *udevDevice = udev_monitor_receive_device(udevMonitor); |
566 | if (!udevDevice) |
567 | return; |
568 | |
569 | if (0 != strcmp(udev_device_get_subsystem(udevDevice), "net" )) |
570 | return; |
571 | |
572 | QString sysname(QString::fromLocal8Bit(udev_device_get_sysname(udevDevice))); |
573 | if (watchNetworkInterfaceCount) { |
574 | if (sysname.startsWith(QLatin1String("eth" )) |
575 | || sysname.startsWith(QLatin1String("usb" )) |
576 | || sysname.startsWith(QLatin1String("enp" ))) { |
577 | if (0 == strcmp(udev_device_get_action(udevDevice), "add" )) |
578 | ++networkInterfaceCounts[QNetworkInfo::EthernetMode]; |
579 | else if (0 == strcmp(udev_device_get_action(udevDevice), "remove" )) |
580 | --networkInterfaceCounts[QNetworkInfo::EthernetMode]; |
581 | emit networkInterfaceCountChanged(QNetworkInfo::EthernetMode, |
582 | networkInterfaceCounts[QNetworkInfo::EthernetMode]); |
583 | } else if (sysname.startsWith(QLatin1String("wlan" )) || sysname.startsWith(QLatin1String("wlp" ))) { |
584 | if (0 == strcmp(udev_device_get_action(udevDevice), "add" )) |
585 | ++networkInterfaceCounts[QNetworkInfo::WlanMode]; |
586 | else if (0 == strcmp(udev_device_get_action(udevDevice), "remove" )) |
587 | --networkInterfaceCounts[QNetworkInfo::WlanMode]; |
588 | emit networkInterfaceCountChanged(QNetworkInfo::WlanMode, |
589 | networkInterfaceCounts[QNetworkInfo::WlanMode]); |
590 | } |
591 | } |
592 | |
593 | udev_device_unref(udevDevice); |
594 | } |
595 | #endif // QT_NO_UDEV |
596 | |
597 | void QNetworkInfoPrivate::onTimeout() |
598 | { |
599 | #if defined(QT_NO_UDEV) |
600 | if (watchNetworkInterfaceCount) { |
601 | QList<QNetworkInfo::NetworkMode> modes; |
602 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
603 | foreach (QNetworkInfo::NetworkMode mode, modes) { |
604 | int value = getNetworkInterfaceCount(mode); |
605 | if (networkInterfaceCounts.value(akey: mode) != value) { |
606 | networkInterfaceCounts[mode] = value; |
607 | emit networkInterfaceCountChanged(mode, count: value); |
608 | } |
609 | } |
610 | } |
611 | #endif // QT_NO_UDEV |
612 | |
613 | if (!watchNetworkSignalStrength && !watchNetworkStatus && !watchNetworkName && !watchCurrentNetworkMode) |
614 | return; |
615 | |
616 | QList<QNetworkInfo::NetworkMode> modes; |
617 | modes << QNetworkInfo::WlanMode << QNetworkInfo::EthernetMode << QNetworkInfo::BluetoothMode; |
618 | foreach (QNetworkInfo::NetworkMode mode, modes) { |
619 | int count = networkInterfaceCount(mode); |
620 | for (int i = 0; i < count; ++i) { |
621 | if (watchNetworkSignalStrength) { |
622 | int value = getNetworkSignalStrength(mode, interface: i); |
623 | QPair<QNetworkInfo::NetworkMode, int> key(mode, i); |
624 | if (networkSignalStrengths.value(akey: key) != value) { |
625 | networkSignalStrengths[key] = value; |
626 | emit networkSignalStrengthChanged(mode, interface: i, strength: value); |
627 | } |
628 | } |
629 | |
630 | if (watchNetworkStatus) { |
631 | QNetworkInfo::NetworkStatus value = getNetworkStatus(mode, interface: i); |
632 | QPair<QNetworkInfo::NetworkMode, int> key(mode, i); |
633 | if (networkStatuses.value(akey: key) != value) { |
634 | networkStatuses[key] = value; |
635 | emit networkStatusChanged(mode, interface: i, status: value); |
636 | } |
637 | } |
638 | |
639 | if (watchNetworkName) { |
640 | QString value = getNetworkName(mode, interface: i); |
641 | QPair<QNetworkInfo::NetworkMode, int> key(mode, i); |
642 | if (networkNames.value(akey: key) != value) { |
643 | networkNames[key] = value; |
644 | emit networkNameChanged(mode, interface: i, name: value); |
645 | } |
646 | } |
647 | } |
648 | } |
649 | |
650 | if (watchCurrentNetworkMode) { |
651 | QNetworkInfo::NetworkMode value = getCurrentNetworkMode(); |
652 | if (currentMode != value) { |
653 | currentMode = value; |
654 | emit currentNetworkModeChanged(mode: value); |
655 | } |
656 | } |
657 | |
658 | } |
659 | |
660 | int QNetworkInfoPrivate::getNetworkInterfaceCount(QNetworkInfo::NetworkMode mode) |
661 | { |
662 | switch (mode) { |
663 | case QNetworkInfo::WlanMode: |
664 | return QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *WLAN_MASK()).size(); |
665 | |
666 | case QNetworkInfo::EthernetMode: |
667 | return QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *ETHERNET_MASK()).size(); |
668 | |
669 | case QNetworkInfo::BluetoothMode: { |
670 | int count = -1; |
671 | #if !defined(QT_NO_BLUEZ) |
672 | int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); |
673 | if (ctl < 0) |
674 | return count; |
675 | struct hci_dev_list_req *deviceList = (struct hci_dev_list_req *)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); |
676 | deviceList->dev_num = HCI_MAX_DEV; |
677 | if (ioctl(fd: ctl, HCIGETDEVLIST, deviceList) == 0) |
678 | count = deviceList->dev_num; |
679 | free(ptr: deviceList); |
680 | close(fd: ctl); |
681 | #endif // QT_NO_BLUEZ |
682 | return count; |
683 | } |
684 | |
685 | case QNetworkInfo::GsmMode: |
686 | case QNetworkInfo::CdmaMode: |
687 | case QNetworkInfo::WcdmaMode: |
688 | case QNetworkInfo::LteMode: |
689 | case QNetworkInfo::TdscdmaMode: |
690 | #if !defined(QT_NO_OFONO) |
691 | if (QOfonoWrapper::isOfonoAvailable()) { |
692 | if (!ofonoWrapper) |
693 | ofonoWrapper = new QOfonoWrapper(this); |
694 | return ofonoWrapper->allModems().size(); |
695 | } |
696 | #endif |
697 | |
698 | // case QNetworkInfo::WimaxMode: |
699 | default: |
700 | return -1; |
701 | }; |
702 | } |
703 | |
704 | int QNetworkInfoPrivate::getNetworkSignalStrength(QNetworkInfo::NetworkMode mode, int interface) |
705 | { |
706 | switch (mode) { |
707 | case QNetworkInfo::WlanMode: { |
708 | QFile file(QString(QStringLiteral("/proc/net/wireless" ))); |
709 | if (!file.open(flags: QIODevice::ReadOnly | QIODevice::Text)) |
710 | return -1; |
711 | |
712 | QTextStream in(&file); |
713 | QString interfaceName = interfaceForMode(mode: QNetworkInfo::WlanMode, interface).name(); |
714 | |
715 | QStringList lines = in.readAll().split(QStringLiteral("\n" )); |
716 | for (int i = 0; i < lines.size(); i++) { |
717 | QString line = lines.at(i); |
718 | if (!line.isNull() && line.left(n: 6).contains(s: interfaceName)) { |
719 | // A typical wireless received signal power over a network falls into the range of (-120, -20), |
720 | // we shift the dbm value, which is read from the field "Quality - level" in "/proc/net/wireless", |
721 | // from (-120, -20) to (0, 100) by adding 120. In case of outliers, we restrict them to the |
722 | // corresponding boundary value. |
723 | QString token = line.section(in_sep: QString(QStringLiteral(" " )), start: 3, end: 3, flags: QString::SectionSkipEmpty).simplified(); |
724 | token.chop(n: 1); |
725 | bool ok; |
726 | int signalStrength = token.toInt(ok: &ok); |
727 | if (ok) { |
728 | signalStrength += 120; |
729 | if (signalStrength > 100) |
730 | signalStrength = 100; |
731 | else if (signalStrength < 0) |
732 | signalStrength = 0; |
733 | return signalStrength; |
734 | } else { |
735 | return -1; |
736 | } |
737 | } |
738 | } |
739 | |
740 | break; |
741 | } |
742 | |
743 | case QNetworkInfo::EthernetMode: |
744 | if (networkStatus(mode: QNetworkInfo::EthernetMode, interface) == QNetworkInfo::HomeNetwork) |
745 | return 100; |
746 | else |
747 | return -1; |
748 | |
749 | case QNetworkInfo::GsmMode: |
750 | case QNetworkInfo::CdmaMode: |
751 | case QNetworkInfo::WcdmaMode: |
752 | case QNetworkInfo::LteMode: |
753 | case QNetworkInfo::TdscdmaMode: |
754 | #if !defined(QT_NO_OFONO) |
755 | if (QOfonoWrapper::isOfonoAvailable()) { |
756 | if (!ofonoWrapper) |
757 | ofonoWrapper = new QOfonoWrapper(this); |
758 | QStringList modems = ofonoWrapper->allModems(); |
759 | if (interface < modems.size()) { |
760 | QString modem = ofonoWrapper->allModems().at(interface); |
761 | if (!modem.isEmpty()) |
762 | return ofonoWrapper->signalStrength(modem); |
763 | } |
764 | } |
765 | #endif |
766 | break; |
767 | |
768 | case QNetworkInfo::BluetoothMode: { |
769 | int signalStrength = -1; |
770 | #if !defined(QT_NO_BLUEZ) |
771 | int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); |
772 | if (ctl < 0) |
773 | break; |
774 | struct hci_dev_list_req *deviceList = (struct hci_dev_list_req *)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); |
775 | deviceList->dev_num = HCI_MAX_DEV; |
776 | if (ioctl(fd: ctl, HCIGETDEVLIST, deviceList) == 0) { |
777 | int count = deviceList->dev_num; |
778 | if (interface < count) { |
779 | signalStrength = 0; // Valid interface |
780 | |
781 | struct hci_conn_list_req *connectionList = (struct hci_conn_list_req *)malloc(size: sizeof(struct hci_conn_info) + sizeof(struct hci_conn_list_req)); |
782 | connectionList->dev_id = (deviceList->dev_req + interface)->dev_id; |
783 | connectionList->conn_num = 1; |
784 | if (ioctl(fd: ctl, HCIGETCONNLIST, connectionList) == 0) { |
785 | if (connectionList->conn_num == 1) { |
786 | int fd = hci_open_dev(dev_id: (deviceList->dev_req + interface)->dev_id); |
787 | if (fd > 0) { |
788 | struct hci_conn_info_req *connectionInfo = (struct hci_conn_info_req *)malloc(size: sizeof(struct hci_conn_info_req) + sizeof(struct hci_conn_info)); |
789 | bacpy(dst: &connectionInfo->bdaddr, src: &connectionList->conn_info->bdaddr); |
790 | connectionInfo->type = ACL_LINK; |
791 | if (ioctl(fd: fd, HCIGETCONNINFO, connectionInfo) == 0) { |
792 | uint8_t linkQuality; |
793 | if (hci_read_link_quality(dd: fd, htobs(connectionInfo->conn_info->handle), link_quality: &linkQuality, to: 0) == 0) |
794 | signalStrength = linkQuality * 100 / 255; |
795 | } |
796 | free(ptr: connectionInfo); |
797 | } |
798 | } |
799 | } |
800 | free (ptr: connectionList); |
801 | } |
802 | } |
803 | free(ptr: deviceList); |
804 | close(fd: ctl); |
805 | #endif // QT_NO_BLUEZ |
806 | return signalStrength; |
807 | } |
808 | |
809 | // case QNetworkInfo::WimaxMode: |
810 | default: |
811 | break; |
812 | }; |
813 | |
814 | return -1; |
815 | } |
816 | |
817 | QNetworkInfo::NetworkMode QNetworkInfoPrivate::getCurrentNetworkMode() |
818 | { |
819 | // TODO multiple-interface support |
820 | if (networkStatus(mode: QNetworkInfo::EthernetMode, interface: 0) == QNetworkInfo::HomeNetwork) |
821 | return QNetworkInfo::EthernetMode; |
822 | else if (networkStatus(mode: QNetworkInfo::WlanMode, interface: 0) == QNetworkInfo::HomeNetwork) |
823 | return QNetworkInfo::WlanMode; |
824 | else if (networkStatus(mode: QNetworkInfo::BluetoothMode, interface: 0) == QNetworkInfo::HomeNetwork) |
825 | return QNetworkInfo::BluetoothMode; |
826 | else if (networkStatus(mode: QNetworkInfo::WimaxMode, interface: 0) == QNetworkInfo::HomeNetwork) |
827 | return QNetworkInfo::WimaxMode; |
828 | else if (networkStatus(mode: QNetworkInfo::LteMode, interface: 0) == QNetworkInfo::HomeNetwork) |
829 | return QNetworkInfo::LteMode; |
830 | else if (networkStatus(mode: QNetworkInfo::WcdmaMode, interface: 0) == QNetworkInfo::HomeNetwork) |
831 | return QNetworkInfo::WcdmaMode; |
832 | else if (networkStatus(mode: QNetworkInfo::CdmaMode, interface: 0) == QNetworkInfo::HomeNetwork) |
833 | return QNetworkInfo::CdmaMode; |
834 | else if (networkStatus(mode: QNetworkInfo::GsmMode, interface: 0) == QNetworkInfo::HomeNetwork) |
835 | return QNetworkInfo::GsmMode; |
836 | else if (networkStatus(mode: QNetworkInfo::TdscdmaMode, interface: 0) == QNetworkInfo::HomeNetwork) |
837 | return QNetworkInfo::TdscdmaMode; |
838 | else if (networkStatus(mode: QNetworkInfo::WimaxMode, interface: 0) == QNetworkInfo::Roaming) |
839 | return QNetworkInfo::WimaxMode; |
840 | else if (networkStatus(mode: QNetworkInfo::LteMode, interface: 0) == QNetworkInfo::Roaming) |
841 | return QNetworkInfo::LteMode; |
842 | else if (networkStatus(mode: QNetworkInfo::WcdmaMode, interface: 0) == QNetworkInfo::Roaming) |
843 | return QNetworkInfo::WcdmaMode; |
844 | else if (networkStatus(mode: QNetworkInfo::CdmaMode, interface: 0) == QNetworkInfo::Roaming) |
845 | return QNetworkInfo::CdmaMode; |
846 | else if (networkStatus(mode: QNetworkInfo::GsmMode, interface: 0) == QNetworkInfo::Roaming) |
847 | return QNetworkInfo::GsmMode; |
848 | else if (networkStatus(mode: QNetworkInfo::TdscdmaMode, interface: 0) == QNetworkInfo::Roaming) |
849 | return QNetworkInfo::TdscdmaMode; |
850 | else |
851 | return QNetworkInfo::UnknownMode; |
852 | } |
853 | |
854 | QNetworkInfo::NetworkStatus QNetworkInfoPrivate::getNetworkStatus(QNetworkInfo::NetworkMode mode, int interface) |
855 | { |
856 | switch (mode) { |
857 | case QNetworkInfo::WlanMode: { |
858 | if (interface < networkInterfaceCount(mode: QNetworkInfo::WlanMode)) { |
859 | const QString fileName = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *WLAN_MASK()).at(i: interface); |
860 | QFile carrier(*NETWORK_SYSFS_PATH() + fileName + QStringLiteral("/carrier" )); |
861 | if (carrier.open(flags: QIODevice::ReadOnly)) { |
862 | char state; |
863 | if ((carrier.read(data: &state, maxlen: 1) == 1) && |
864 | (state == '1')) { |
865 | return QNetworkInfo::HomeNetwork; |
866 | } |
867 | } |
868 | } |
869 | return QNetworkInfo::NoNetworkAvailable; |
870 | } |
871 | |
872 | case QNetworkInfo::EthernetMode: { |
873 | if (interface < networkInterfaceCount(mode: QNetworkInfo::EthernetMode)) { |
874 | const QString fileName = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *ETHERNET_MASK()).at(i: interface); |
875 | QFile carrier(*NETWORK_SYSFS_PATH() + fileName + QStringLiteral("/carrier" )); |
876 | if (carrier.open(flags: QIODevice::ReadOnly)) { |
877 | char state; |
878 | if ((carrier.read(data: &state, maxlen: 1) == 1) && (state == '1')) |
879 | return QNetworkInfo::HomeNetwork; |
880 | } |
881 | } |
882 | return QNetworkInfo::NoNetworkAvailable; |
883 | } |
884 | |
885 | case QNetworkInfo::BluetoothMode: { |
886 | QNetworkInfo::NetworkStatus status = QNetworkInfo::UnknownStatus; |
887 | |
888 | #if !defined(QT_NO_BLUEZ) |
889 | int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); |
890 | if (ctl < 0) |
891 | break; |
892 | struct hci_dev_list_req *deviceList = (struct hci_dev_list_req *)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); |
893 | deviceList->dev_num = HCI_MAX_DEV; |
894 | if (ioctl(fd: ctl, HCIGETDEVLIST, deviceList) == 0) { |
895 | int count = deviceList->dev_num; |
896 | if (interface < count) { |
897 | status = QNetworkInfo::NoNetworkAvailable; // Valid interface, so either not connected or connected |
898 | // TODO add support for searching and denied |
899 | struct hci_conn_list_req *connectionList = (struct hci_conn_list_req *)malloc(size: sizeof(struct hci_conn_info) + sizeof(struct hci_conn_list_req)); |
900 | connectionList->dev_id = (deviceList->dev_req + interface)->dev_id; |
901 | connectionList->conn_num = 1; |
902 | if (ioctl(fd: ctl, HCIGETCONNLIST, connectionList) == 0) { |
903 | if (connectionList->conn_num == 1) |
904 | status = QNetworkInfo::HomeNetwork; |
905 | } |
906 | free (ptr: connectionList); |
907 | } |
908 | } |
909 | free(ptr: deviceList); |
910 | close(fd: ctl); |
911 | #endif // QT_NO_BLUEZ |
912 | |
913 | return status; |
914 | } |
915 | |
916 | case QNetworkInfo::GsmMode: |
917 | case QNetworkInfo::CdmaMode: |
918 | case QNetworkInfo::WcdmaMode: |
919 | case QNetworkInfo::LteMode: |
920 | case QNetworkInfo::TdscdmaMode: |
921 | #if !defined(QT_NO_OFONO) |
922 | if (QOfonoWrapper::isOfonoAvailable()) { |
923 | if (!ofonoWrapper) |
924 | ofonoWrapper = new QOfonoWrapper(this); |
925 | QStringList modems = ofonoWrapper->allModems(); |
926 | if (interface < modems.size()) { |
927 | QString modem = ofonoWrapper->allModems().at(interface); |
928 | if (!modem.isEmpty()) |
929 | return ofonoWrapper->networkStatus(modem); |
930 | } |
931 | } |
932 | #endif |
933 | break; |
934 | |
935 | // case QNetworkInfo::WimaxMode: |
936 | default: |
937 | break; |
938 | }; |
939 | |
940 | return QNetworkInfo::UnknownStatus; |
941 | } |
942 | |
943 | QString QNetworkInfoPrivate::getNetworkName(QNetworkInfo::NetworkMode mode, int interface) |
944 | { |
945 | switch (mode) { |
946 | case QNetworkInfo::WlanMode: { |
947 | if (interface < networkInterfaceCount(mode: QNetworkInfo::WlanMode)) { |
948 | int sock = socket(PF_INET, SOCK_DGRAM, protocol: 0); |
949 | if (sock > 0) { |
950 | char buffer[IW_ESSID_MAX_SIZE + 1]; |
951 | iwreq iwInfo; |
952 | |
953 | iwInfo.u.essid.pointer = (caddr_t)&buffer; |
954 | iwInfo.u.essid.length = IW_ESSID_MAX_SIZE + 1; |
955 | iwInfo.u.essid.flags = 0; |
956 | for (int i = 0; i < WLAN_MASK()->count(); i++) { |
957 | const QString fileName = QDir(*NETWORK_SYSFS_PATH()).entryList(nameFilters: *WLAN_MASK()).at(i: interface); |
958 | strncpy(dest: iwInfo.ifr_name, src: fileName.toLocal8Bit().constData(), IFNAMSIZ); |
959 | if (ioctl(fd: sock, SIOCGIWESSID, &iwInfo) == 0) { |
960 | close(fd: sock); |
961 | return QString::fromLatin1(str: (const char *)iwInfo.u.essid.pointer); |
962 | } else { |
963 | qDebug() << "ioctl failed" ; |
964 | } |
965 | |
966 | close(fd: sock); |
967 | |
968 | } |
969 | } |
970 | } |
971 | break; |
972 | } |
973 | |
974 | case QNetworkInfo::EthernetMode: { |
975 | // TODO multiple-interface support |
976 | char domainName[64]; |
977 | if (getdomainname(name: domainName, len: 64) == 0) { |
978 | if (strcmp(s1: domainName, s2: "(none)" ) != 0) |
979 | return QString::fromLatin1(str: domainName); |
980 | else |
981 | return QStringLiteral("Unknown" ); |
982 | } |
983 | break; |
984 | } |
985 | |
986 | case QNetworkInfo::BluetoothMode: { |
987 | #if !defined(QT_NO_BLUEZ) |
988 | int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); |
989 | if (ctl < 0) |
990 | break; |
991 | struct hci_dev_list_req *deviceList = (struct hci_dev_list_req *)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); |
992 | deviceList->dev_num = HCI_MAX_DEV; |
993 | QString networkName; |
994 | if (ioctl(fd: ctl, HCIGETDEVLIST, deviceList) == 0) { |
995 | int count = deviceList->dev_num; |
996 | if (interface < count) { |
997 | int fd = hci_open_dev(dev_id: (deviceList->dev_req + interface)->dev_id); |
998 | if (fd > 0) { |
999 | char name[249]; |
1000 | if (hci_read_local_name(dd: fd, len: sizeof(name), name, to: 0) == 0) |
1001 | networkName = QString::fromLatin1(str: name); |
1002 | } |
1003 | } |
1004 | } |
1005 | free(ptr: deviceList); |
1006 | close(fd: ctl); |
1007 | return networkName; |
1008 | #endif // QT_NO_BLUEZ |
1009 | break; |
1010 | } |
1011 | |
1012 | case QNetworkInfo::GsmMode: |
1013 | case QNetworkInfo::CdmaMode: |
1014 | case QNetworkInfo::WcdmaMode: |
1015 | case QNetworkInfo::LteMode: |
1016 | case QNetworkInfo::TdscdmaMode: |
1017 | #if !defined(QT_NO_OFONO) |
1018 | if (QOfonoWrapper::isOfonoAvailable()) { |
1019 | if (!ofonoWrapper) |
1020 | ofonoWrapper = new QOfonoWrapper(this); |
1021 | QStringList modems = ofonoWrapper->allModems(); |
1022 | if (interface < modems.size()) { |
1023 | QString modem = ofonoWrapper->allModems().at(interface); |
1024 | if (!modem.isEmpty()) |
1025 | return ofonoWrapper->operatorName(modem); |
1026 | } |
1027 | } |
1028 | #endif |
1029 | break; |
1030 | |
1031 | // case QNetworkInfo::WimaxMode: |
1032 | default: |
1033 | break; |
1034 | }; |
1035 | |
1036 | return QString(); |
1037 | } |
1038 | |
1039 | QT_END_NAMESPACE |
1040 | |