diff options
Diffstat (limited to 'src/imports/wifi/qwifinetworklistmodel.cpp')
-rw-r--r-- | src/imports/wifi/qwifinetworklistmodel.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/imports/wifi/qwifinetworklistmodel.cpp b/src/imports/wifi/qwifinetworklistmodel.cpp new file mode 100644 index 0000000..4fbf25f --- /dev/null +++ b/src/imports/wifi/qwifinetworklistmodel.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://qt.digia.com/ +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://qt.digia.com/ +** +****************************************************************************/ +#include "qwifinetworklistmodel.h" + +#include <QtCore> + +const int ID_NETWORK = (Qt::ItemDataRole) (Qt::UserRole + 1); + +QWifiNetworkListModel::QWifiNetworkListModel(QWifiManager *manager) + : m_manager(manager) +{ +} + +QWifiNetworkListModel::~QWifiNetworkListModel() +{ + qDeleteAll(m_networks); + qDeleteAll(m_outOfRangeNetworks); + m_networks.clear(); + m_outOfRangeNetworks.clear(); +} + +QHash<int, QByteArray> QWifiNetworkListModel::roleNames() const +{ + QHash<int, QByteArray> names; + names.insert(ID_NETWORK, "network"); + return names; +} + +QVariant QWifiNetworkListModel::data(const QModelIndex &index, int role) const +{ + QWifiNetwork *n = m_networks.at(index.row()); + switch (role) { + case ID_NETWORK: return QVariant::fromValue((QObject *) n); + } + + qWarning("QWifiNetworkListModel::data(), undefined role: %d\n", role); + + return QVariant(); +} + +QWifiNetwork *QWifiNetworkListModel::networkForSSID(const QByteArray &ssid, int *pos) +{ + for (int i = 0; i < m_networks.size(); ++i) { + if (m_networks.at(i)->ssid() == ssid) { + if (pos) + *pos = i; + return m_networks.at(i); + } + } + return 0; +} + +QWifiNetwork *QWifiNetworkListModel::outOfRangeListContains(const QByteArray &ssid) +{ + for (int i = 0; i < m_outOfRangeNetworks.length(); ++i) + if (m_outOfRangeNetworks.at(i)->ssid() == ssid) + return m_outOfRangeNetworks.takeAt(i); + return 0; +} + +void QWifiNetworkListModel::parseScanResults(const QByteArray &results) +{ + QList<QByteArray> lines = results.split('\n'); + QSet<QByteArray> sensibleNetworks; + + for (int i = 1; i < lines.size(); ++i) { + QList<QByteArray> info = lines.at(i).split('\t'); + if (info.size() < 5 || info.at(4).isEmpty() || info.at(0).isEmpty()) + continue; + int pos = 0; + sensibleNetworks.insert(info.at(4)); + QWifiNetwork *knownNetwork = networkForSSID(info.at(4), &pos); + if (!knownNetwork) + knownNetwork = outOfRangeListContains(info.at(4)); + + if (!knownNetwork) { + QWifiNetwork *network = new QWifiNetwork(); + network->setOutOfRange(false); + network->setBssid(info.at(0)); + network->setFlags(info.at(3)); + // signal strength is in dBm + network->setSignalStrength(info.at(2).toInt()); + network->setSsid(info.at(4)); + beginInsertRows(QModelIndex(), m_networks.size(), m_networks.size()); + m_networks << network; + endInsertRows(); + } else { + if (knownNetwork->outOfRange()) { + // known network has come back into a range + knownNetwork->setOutOfRange(false); + beginInsertRows(QModelIndex(), m_networks.size(), m_networks.size()); + m_networks << knownNetwork; + endInsertRows(); + pos = m_networks.length() - 1; + } + // ssids are the same, compare bssids.. + if (knownNetwork->bssid() == info.at(0)) { + // same access point, simply update the signal strength + knownNetwork->setSignalStrength(info.at(2).toInt()); + knownNetwork->setOutOfRange(false); + dataChanged(createIndex(pos, 0), createIndex(pos, 0)); + } else if (knownNetwork->signalStrength() < info.at(2).toInt()) { + // replace with a stronger access point within the same network + m_networks.at(pos)->setOutOfRange(false); + m_networks.at(pos)->setBssid(info.at(0)); + m_networks.at(pos)->setFlags(info.at(3)); + m_networks.at(pos)->setSignalStrength(info.at(2).toInt()); + m_networks.at(pos)->setSsid(info.at(4)); + dataChanged(createIndex(pos, 0), createIndex(pos, 0)); + } + } + } + // remove out-of-range networks from the data model + for (int i = 0; i < m_networks.size();) { + if (!sensibleNetworks.contains(m_networks.at(i)->ssid())) { + beginRemoveRows(QModelIndex(), i, i); + QWifiNetwork *n = m_networks.takeAt(i); + n->setOutOfRange(true); + m_outOfRangeNetworks.append(n); + endRemoveRows(); + } else { + ++i; + } + } +} |