| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the examples of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:BSD$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** BSD License Usage |
| ** Alternatively, you may use this file under the terms of the BSD license |
| ** as follows: |
| ** |
| ** "Redistribution and use in source and binary forms, with or without |
| ** modification, are permitted provided that the following conditions are |
| ** met: |
| ** * Redistributions of source code must retain the above copyright |
| ** notice, this list of conditions and the following disclaimer. |
| ** * Redistributions in binary form must reproduce the above copyright |
| ** notice, this list of conditions and the following disclaimer in |
| ** the documentation and/or other materials provided with the |
| ** distribution. |
| ** * Neither the name of The Qt Company Ltd nor the names of its |
| ** contributors may be used to endorse or promote products derived |
| ** from this software without specific prior written permission. |
| ** |
| ** |
| ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "bearermonitor.h" |
| #include "sessionwidget.h" |
| |
| #include <QtCore/QDebug> |
| |
| #ifdef Q_OS_WIN |
| #include <winsock2.h> |
| #undef interface |
| |
| #ifndef NS_NLA |
| #define NS_NLA 15 |
| #endif |
| #endif |
| |
| BearerMonitor::BearerMonitor(QWidget *parent) |
| : QWidget(parent) |
| { |
| setupUi(this); |
| delete tabWidget->currentWidget(); |
| sessionGroup->hide(); |
| updateConfigurations(); |
| onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty()); |
| QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration(); |
| for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { |
| QTreeWidgetItem *item = treeWidget->topLevelItem(i); |
| |
| if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) { |
| treeWidget->setCurrentItem(item); |
| showConfigurationFor(item); |
| break; |
| } |
| } |
| connect(&manager, SIGNAL(onlineStateChanged(bool)), this ,SLOT(onlineStateChanged(bool))); |
| connect(&manager, SIGNAL(configurationAdded(const QNetworkConfiguration&)), |
| this, SLOT(configurationAdded(const QNetworkConfiguration&))); |
| connect(&manager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)), |
| this, SLOT(configurationRemoved(const QNetworkConfiguration&))); |
| connect(&manager, SIGNAL(configurationChanged(const QNetworkConfiguration&)), |
| this, SLOT(configurationChanged(const QNetworkConfiguration))); |
| connect(&manager, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations())); |
| |
| #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) |
| connect(registerButton, SIGNAL(clicked()), this, SLOT(registerNetwork())); |
| connect(unregisterButton, SIGNAL(clicked()), this, SLOT(unregisterNetwork())); |
| #else // Q_OS_WIN && !Q_OS_WINRT |
| nlaGroup->hide(); |
| #endif |
| |
| connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), |
| this, SLOT(createSessionFor(QTreeWidgetItem*))); |
| |
| connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), |
| this, SLOT(showConfigurationFor(QTreeWidgetItem*))); |
| |
| connect(newSessionButton, SIGNAL(clicked()), |
| this, SLOT(createNewSession())); |
| connect(deleteSessionButton, SIGNAL(clicked()), |
| this, SLOT(deleteSession())); |
| connect(scanButton, SIGNAL(clicked()), |
| this, SLOT(performScan())); |
| |
| // Just in case update all configurations so that all |
| // configurations are up to date. |
| manager.updateConfigurations(); |
| } |
| |
| BearerMonitor::~BearerMonitor() |
| { |
| } |
| |
| static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config) |
| { |
| item->setText(0, config.name()); |
| item->setData(0, Qt::UserRole, config.identifier()); |
| |
| QFont font = item->font(1); |
| font.setBold((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active); |
| item->setFont(0, font); |
| } |
| |
| void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent) |
| { |
| if (!config.isValid()) |
| return; |
| |
| QTreeWidgetItem *item = new QTreeWidgetItem; |
| updateItem(item, config); |
| |
| if (parent) |
| parent->addChild(item); |
| else |
| treeWidget->addTopLevelItem(item); |
| |
| if (config.type() == QNetworkConfiguration::ServiceNetwork) { |
| const QList<QNetworkConfiguration> children = config.children(); |
| for (const QNetworkConfiguration &child : children) |
| configurationAdded(child, item); |
| } |
| } |
| |
| void BearerMonitor::configurationRemoved(const QNetworkConfiguration &config) |
| { |
| for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { |
| QTreeWidgetItem *item = treeWidget->topLevelItem(i); |
| |
| if (item->data(0, Qt::UserRole).toString() == config.identifier()) { |
| delete item; |
| break; |
| } |
| } |
| } |
| |
| void BearerMonitor::configurationChanged(const QNetworkConfiguration &config) |
| { |
| for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { |
| QTreeWidgetItem *item = treeWidget->topLevelItem(i); |
| |
| if (item->data(0, Qt::UserRole).toString() == config.identifier()) { |
| updateItem(item, config); |
| |
| if (config.type() == QNetworkConfiguration::ServiceNetwork) |
| updateSnapConfiguration(item, config); |
| |
| if (item == treeWidget->currentItem()) |
| showConfigurationFor(item); |
| |
| break; |
| } |
| } |
| } |
| |
| void BearerMonitor::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap) |
| { |
| QMap<QString, QTreeWidgetItem *> itemMap; |
| const QList<QTreeWidgetItem *> children = parent->takeChildren(); |
| for (QTreeWidgetItem *item : children) |
| itemMap.insert(item->data(0, Qt::UserRole).toString(), item); |
| |
| QList<QNetworkConfiguration> allConfigurations = snap.children(); |
| |
| while (!allConfigurations.isEmpty()) { |
| QNetworkConfiguration config = allConfigurations.takeFirst(); |
| |
| QTreeWidgetItem *item = itemMap.take(config.identifier()); |
| if (item) { |
| updateItem(item, config); |
| |
| parent->addChild(item); |
| |
| if (config.type() == QNetworkConfiguration::ServiceNetwork) |
| updateSnapConfiguration(item, config); |
| } else { |
| configurationAdded(config, parent); |
| } |
| } |
| |
| qDeleteAll(itemMap); |
| } |
| |
| void BearerMonitor::updateConfigurations() |
| { |
| progressBar->hide(); |
| scanButton->show(); |
| |
| // Just in case update online state, on Symbian platform |
| // WLAN scan needs to be triggered initially to have their true state. |
| onlineStateChanged(manager.isOnline()); |
| |
| QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard); |
| QMap<QString, QTreeWidgetItem *> itemMap; |
| while (!items.isEmpty()) { |
| QTreeWidgetItem *item = items.takeFirst(); |
| itemMap.insert(item->data(0, Qt::UserRole).toString(), item); |
| } |
| |
| QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration(); |
| QTreeWidgetItem *defaultItem = itemMap.take(defaultConfiguration.identifier()); |
| |
| if (defaultItem) { |
| updateItem(defaultItem, defaultConfiguration); |
| |
| if (defaultConfiguration.type() == QNetworkConfiguration::ServiceNetwork) |
| updateSnapConfiguration(defaultItem, defaultConfiguration); |
| } else { |
| configurationAdded(defaultConfiguration); |
| } |
| |
| QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations(); |
| |
| while (!allConfigurations.isEmpty()) { |
| QNetworkConfiguration config = allConfigurations.takeFirst(); |
| |
| if (config.identifier() == defaultConfiguration.identifier()) |
| continue; |
| |
| QTreeWidgetItem *item = itemMap.take(config.identifier()); |
| if (item) { |
| updateItem(item, config); |
| |
| if (config.type() == QNetworkConfiguration::ServiceNetwork) |
| updateSnapConfiguration(item, config); |
| } else { |
| configurationAdded(config); |
| } |
| } |
| |
| qDeleteAll(itemMap); |
| } |
| |
| void BearerMonitor::onlineStateChanged(bool isOnline) |
| { |
| if (isOnline) |
| onlineState->setText(tr("Online")); |
| else |
| onlineState->setText(tr("Offline")); |
| } |
| |
| #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) |
| void BearerMonitor::registerNetwork() |
| { |
| QTreeWidgetItem *item = treeWidget->currentItem(); |
| if (!item) return; |
| |
| QNetworkConfiguration configuration = |
| manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString()); |
| |
| const QString name = configuration.name(); |
| |
| qDebug() << "Registering" << name << "with system"; |
| |
| WSAQUERYSET networkInfo; |
| memset(&networkInfo, 0, sizeof(networkInfo)); |
| networkInfo.dwSize = sizeof(networkInfo); |
| networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16(); |
| networkInfo.dwNameSpace = NS_NLA; |
| |
| if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR) |
| qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError(); |
| } |
| |
| void BearerMonitor::unregisterNetwork() |
| { |
| QTreeWidgetItem *item = treeWidget->currentItem(); |
| if (!item) return; |
| |
| QNetworkConfiguration configuration = |
| manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString()); |
| |
| const QString name = configuration.name(); |
| |
| qDebug() << "Unregistering" << name << "with system"; |
| |
| WSAQUERYSET networkInfo; |
| memset(&networkInfo, 0, sizeof(networkInfo)); |
| networkInfo.dwSize = sizeof(networkInfo); |
| networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16(); |
| networkInfo.dwNameSpace = NS_NLA; |
| |
| if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR) |
| qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError(); |
| } |
| #endif // Q_OS_WIN && !Q_OS_WINRT |
| |
| void BearerMonitor::showConfigurationFor(QTreeWidgetItem *item) |
| { |
| QString identifier; |
| |
| if (item) |
| identifier = item->data(0, Qt::UserRole).toString(); |
| |
| QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier); |
| |
| switch (conf.state()) { |
| case QNetworkConfiguration::Active: |
| configurationState->setText(tr("Active")); |
| break; |
| case QNetworkConfiguration::Discovered: |
| configurationState->setText(tr("Discovered")); |
| break; |
| case QNetworkConfiguration::Defined: |
| configurationState->setText(tr("Defined")); |
| break; |
| case QNetworkConfiguration::Undefined: |
| configurationState->setText(tr("Undefined")); |
| break; |
| default: |
| configurationState->setText(QString()); |
| } |
| |
| switch (conf.type()) { |
| case QNetworkConfiguration::InternetAccessPoint: |
| configurationType->setText(tr("Internet Access Point")); |
| break; |
| case QNetworkConfiguration::ServiceNetwork: |
| configurationType->setText(tr("Service Network")); |
| break; |
| case QNetworkConfiguration::UserChoice: |
| configurationType->setText(tr("User Choice")); |
| break; |
| case QNetworkConfiguration::Invalid: |
| configurationType->setText(tr("Invalid")); |
| break; |
| default: |
| configurationType->setText(QString()); |
| } |
| |
| switch (conf.purpose()) { |
| case QNetworkConfiguration::UnknownPurpose: |
| configurationPurpose->setText(tr("Unknown")); |
| break; |
| case QNetworkConfiguration::PublicPurpose: |
| configurationPurpose->setText(tr("Public")); |
| break; |
| case QNetworkConfiguration::PrivatePurpose: |
| configurationPurpose->setText(tr("Private")); |
| break; |
| case QNetworkConfiguration::ServiceSpecificPurpose: |
| configurationPurpose->setText(tr("Service Specific")); |
| break; |
| default: |
| configurationPurpose->setText(QString()); |
| } |
| |
| configurationIdentifier->setText(conf.identifier()); |
| |
| configurationRoaming->setText(conf.isRoamingAvailable() ? tr("Available") : tr("Not available")); |
| |
| configurationChildren->setText(QString::number(conf.children().count())); |
| |
| configurationName->setText(conf.name()); |
| } |
| |
| void BearerMonitor::createSessionFor(QTreeWidgetItem *item) |
| { |
| const QString identifier = item->data(0, Qt::UserRole).toString(); |
| |
| QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier); |
| |
| SessionWidget *session = new SessionWidget(conf); |
| |
| tabWidget->addTab(session, conf.name()); |
| |
| sessionGroup->show(); |
| |
| sessionWidgets.append(session); |
| } |
| |
| void BearerMonitor::createNewSession() |
| { |
| QTreeWidgetItem *item = treeWidget->currentItem(); |
| if (!item) return; |
| |
| createSessionFor(item); |
| } |
| |
| void BearerMonitor::deleteSession() |
| { |
| SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget()); |
| if (session) { |
| sessionWidgets.removeAll(session); |
| |
| delete session; |
| |
| if (tabWidget->count() == 0) |
| sessionGroup->hide(); |
| } |
| } |
| |
| void BearerMonitor::performScan() |
| { |
| scanButton->hide(); |
| progressBar->show(); |
| manager.updateConfigurations(); |
| } |