From fa977a4aee2a163e7d49033c9365382ef3c2105f Mon Sep 17 00:00:00 2001 From: Antti Lamminsalo Date: Fri, 18 Mar 2016 14:19:30 +0200 Subject: [PATCH] Networking fix for selecting correct interface for accessmanager --- src/network/networkmanager.cpp | 102 +++++++++++++++++++++++++++++++-- src/network/networkmanager.h | 10 +++- src/network/urls.h | 1 + src/qml/components/Channel.qml | 2 +- 4 files changed, 109 insertions(+), 6 deletions(-) diff --git a/src/network/networkmanager.cpp b/src/network/networkmanager.cpp index c9699b1..697364f 100644 --- a/src/network/networkmanager.cpp +++ b/src/network/networkmanager.cpp @@ -2,14 +2,15 @@ #include "../util/fileutils.h" #include "../util/jsonparser.h" #include "../util/m3u8parser.h" +#include +#include NetworkManager::NetworkManager() { operation = new QNetworkAccessManager(); - //Set configuration - conf = new QNetworkConfigurationManager(); - operation->setConfiguration(conf->defaultConfiguration()); + //Select interface + selectNetworkInterface(); //SSL errors handle (down the drain) connect(operation, SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(handleSslErrors(QNetworkReply*,QList))); @@ -22,7 +23,100 @@ NetworkManager::~NetworkManager() { qDebug() << "Destroyer: NetworkManager"; operation->deleteLater(); - conf->deleteLater(); +} + +void NetworkManager::selectNetworkInterface() +{ + //Chooses a working network interface from interfaces list, if default configuration doesn't work + + QNetworkConfigurationManager conf; + connectionOK = false; + QString identifier; + + QEventLoop loop; + connect(this, SIGNAL(finishedConnectionTest()), &loop, SLOT(quit())); + + //Test default configuration + operation->setConfiguration(conf.defaultConfiguration()); + + testConnection(); + loop.exec(); + + if (connectionOK == true) { + qDebug() << "Selected default network configuration"; + return; + } + + else { + qDebug() << "Failure on default configuration, attempt to choose another interaface.."; + + foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) + { + if (!interface.isValid()) + continue; + +// qDebug() << "Identifier: " << interface.name(); +// qDebug() << "HW addr: " << interface.hardwareAddress(); + + bool isUp = interface.flags().testFlag(QNetworkInterface::IsUp); + bool isLoopback = interface.flags().testFlag(QNetworkInterface::IsLoopBack); + bool isActive = interface.flags().testFlag(QNetworkInterface::IsRunning); + bool isPtP = interface.flags().testFlag(QNetworkInterface::IsPointToPoint); + +// qDebug() << "Properties: "; +// qDebug() << (isUp ? "Is up" : "Is down"); + +// if (isLoopback) +// qDebug() << "Loopback"; + +// qDebug() << (isActive ? "Active" : "Inactive"); + +// if (isPtP) +// qDebug() << "Is Point-to-Point"; + +// qDebug() << ""; + + if (isUp && isActive && !isLoopback) { + identifier = interface.name(); + qDebug() << "Testing connection for interface " << identifier; + operation->setConfiguration(conf.configurationFromIdentifier(identifier)); + + testConnection(); + loop.exec(); + + if (connectionOK == true) { + qDebug() << "Success!"; + return; + } + + else + qDebug() << "Failure, trying another interface..."; + } + + } + } +} + +void NetworkManager::testConnection() +{ + QNetworkRequest request; + request.setUrl(QUrl(TWITCH_API_BASE)); + + QNetworkReply *reply = operation->get(request); + + connect(reply, SIGNAL(finished()), this, SLOT(testConnectionReply())); +} + +void NetworkManager::testConnectionReply() +{ + QNetworkReply* reply = qobject_cast(sender()); + +// if (reply->error() == QNetworkReply::NoError) +// qDebug() << "Got response: " << reply->readAll(); + + connectionOK = (reply->error() == QNetworkReply::NoError); + + emit finishedConnectionTest(); } void NetworkManager::getStreams(const QString &url) diff --git a/src/network/networkmanager.h b/src/network/networkmanager.h index 7a3692e..4b9d815 100644 --- a/src/network/networkmanager.h +++ b/src/network/networkmanager.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,9 @@ class NetworkManager: public QObject protected: + void selectNetworkInterface(); + void testConnection(); + enum M3U8TYPE { LIVE = QNetworkRequest::CustomVerbAttribute + 1, VOD @@ -49,6 +53,8 @@ class NetworkManager: public QObject QNetworkAccessManager *getManager() const; signals: + void finishedConnectionTest(); + void allStreamsOperationFinished(const QList&); void gamesOperationFinished(const QList&); void gameStreamsOperationFinished(const QList&); @@ -63,6 +69,7 @@ class NetworkManager: public QObject void fileOperationFinished(const QByteArray&); private slots: + void testConnectionReply(); void handleSslErrors(QNetworkReply * reply, QList errors); void allStreamsReply(); @@ -78,7 +85,8 @@ private slots: private: QNetworkAccessManager *operation; - QNetworkConfigurationManager *conf; + + bool connectionOK; }; #endif // NETWORKMANAGER_H diff --git a/src/network/urls.h b/src/network/urls.h index b1c3de0..1795d1c 100644 --- a/src/network/urls.h +++ b/src/network/urls.h @@ -3,5 +3,6 @@ #define KRAKEN_API "https://api.twitch.tv/kraken" #define TWITCH_API "https://api.twitch.tv/api" +#define TWITCH_API_BASE "https://api.twitch.tv/kraken/base" #endif // URLS_H diff --git a/src/qml/components/Channel.qml b/src/qml/components/Channel.qml index 5a118b0..8c3524a 100644 --- a/src/qml/components/Channel.qml +++ b/src/qml/components/Channel.qml @@ -63,7 +63,7 @@ Rectangle { } onProgressChanged: { - if (progress >= 1.0) + if (progress > 0.99) _spinner.visible = false }