| /**************************************************************************** |
| ** |
| ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |
| ** All rights reserved. |
| ** Contact: Nokia Corporation (qt-info@nokia.com) |
| ** |
| ** This file is part of the FOO module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** GNU Lesser General Public License Usage |
| ** This file may be used under the terms of the GNU Lesser General Public |
| ** License version 2.1 as published by the Free Software Foundation and |
| ** appearing in the file LICENSE.LGPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU Lesser |
| ** General Public License version 2.1 requirements will be met: |
| ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| ** |
| ** In addition, as a special exception, Nokia gives you certain additional |
| ** rights. These rights are described in the Nokia Qt LGPL Exception |
| ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU General |
| ** Public License version 3.0 as published by the Free Software Foundation |
| ** and appearing in the file LICENSE.GPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU General |
| ** Public License version 3.0 requirements will be met: |
| ** http://www.gnu.org/copyleft/gpl.html. |
| ** |
| ** Other Usage |
| ** Alternatively, this file may be used in accordance with the terms and |
| ** conditions contained in a signed written agreement between you and Nokia. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /** |
| * Some notes about the code: |
| * |
| * ** It is assumed that the system proxies are for url based requests |
| * ie. HTTP/HTTPS based. |
| * ** It is assumed that proxies don't use authentication. |
| * ** It is assumed that there is no exceptions to proxy use (Symbian side |
| * does have the field for it but it is not user modifiable by default). |
| * ** There is no checking for protocol name. |
| */ |
| |
| #include <QtNetwork/qnetworkproxy.h> |
| |
| #ifndef QT_NO_NETWORKPROXY |
| |
| #include <metadatabase.h> // CMDBSession |
| #include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord |
| #include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord |
| #include <QtNetwork/QNetworkConfigurationManager> |
| #include <QFlags> |
| |
| using namespace CommsDat; |
| |
| QT_BEGIN_NAMESPACE |
| |
| class SymbianIapId |
| { |
| public: |
| enum State{ |
| NotValid, |
| Valid |
| }; |
| Q_DECLARE_FLAGS(States, State) |
| SymbianIapId() {} |
| ~SymbianIapId() {} |
| void setIapId(TUint32 iapId) { iapState |= Valid; id = iapId; } |
| bool isValid() { return iapState == Valid; } |
| TUint32 iapId() { return id; } |
| private: |
| QFlags<States> iapState; |
| TUint32 id; |
| }; |
| |
| Q_DECLARE_OPERATORS_FOR_FLAGS(SymbianIapId::States) |
| |
| class SymbianProxyQuery |
| { |
| public: |
| static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager); |
| static SymbianIapId getIapId(QNetworkConfigurationManager& configurationManager); |
| static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb); |
| static CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType); |
| static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query); |
| }; |
| |
| QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfigurationManager& configurationManager) |
| { |
| QList<QNetworkConfiguration> activeConfigurations = configurationManager.allConfigurations( |
| QNetworkConfiguration::Active); |
| QNetworkConfiguration currentConfig; |
| if (activeConfigurations.count() > 0) { |
| currentConfig = activeConfigurations.at(0); |
| } else { |
| // No active configurations, try default one |
| QNetworkConfiguration defaultConfiguration = configurationManager.defaultConfiguration(); |
| if (defaultConfiguration.isValid()) { |
| switch (defaultConfiguration.type()) { |
| case QNetworkConfiguration::InternetAccessPoint: |
| currentConfig = defaultConfiguration; |
| break; |
| case QNetworkConfiguration::ServiceNetwork: |
| { |
| // Note: This code assumes that the only unambigious way to |
| // find current proxy config is if there is only one access point |
| // or if the found access point is immediately usable. |
| QList<QNetworkConfiguration> childConfigurations = defaultConfiguration.children(); |
| if (childConfigurations.count() == 1) { |
| currentConfig = childConfigurations.at(0); |
| } else { |
| for (int index = 0; index < childConfigurations.count(); index++) { |
| QNetworkConfiguration childConfig = childConfigurations.at(index); |
| if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Discovered) { |
| currentConfig = childConfig; |
| break; |
| } |
| } |
| } |
| } |
| break; |
| case QNetworkConfiguration::UserChoice: |
| // User choice is not a valid configuration for proxy discovery |
| break; |
| } |
| } |
| } |
| return currentConfig; |
| } |
| |
| SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager) |
| { |
| SymbianIapId iapId; |
| |
| QNetworkConfiguration currentConfig = findCurrentConfiguration(configurationManager); |
| if (currentConfig.isValid()) { |
| // Note: the following code assumes that the identifier is in format |
| // I_xxxx where xxxx is the identifier of IAP. This is meant as a |
| // temporary solution until there is a support for returning |
| // implementation specific identifier. |
| const int generalPartLength = 2; |
| const int identifierNumberLength = currentConfig.identifier().length() - generalPartLength; |
| QString idString(currentConfig.identifier().right(identifierNumberLength)); |
| bool success; |
| uint id = idString.toUInt(&success); |
| if (success) |
| iapId.setIapId(id); |
| else |
| qWarning() << "Failed to convert identifier to access point identifier: " |
| << currentConfig.identifier(); |
| } |
| |
| return iapId; |
| } |
| |
| CCDIAPRecord *SymbianProxyQuery::getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb) |
| { |
| CCDIAPRecord *iap = static_cast<CCDIAPRecord*> (CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord)); |
| CleanupStack::PushL(iap); |
| iap->SetRecordId(aIAPId); |
| iap->LoadL(aDb); |
| return iap; |
| } |
| |
| CMDBRecordSet<CCDProxiesRecord> *SymbianProxyQuery::prepareQueryLC(TUint32 serviceId, TDesC& serviceType) |
| { |
| // Create a recordset of type CCDProxiesRecord |
| // for priming search. |
| // This will ultimately contain record(s) |
| // matching the priming record attributes |
| CMDBRecordSet<CCDProxiesRecord> *proxyRecords = new (ELeave) CMDBRecordSet<CCDProxiesRecord> ( |
| KCDTIdProxiesRecord); |
| CleanupStack::PushL(proxyRecords); |
| |
| CCDProxiesRecord *primingProxyRecord = |
| static_cast<CCDProxiesRecord *> (CCDRecordBase::RecordFactoryL(KCDTIdProxiesRecord)); |
| CleanupStack::PushL(primingProxyRecord); |
| |
| primingProxyRecord->iServiceType.SetMaxLengthL(serviceType.Length()); |
| primingProxyRecord->iServiceType = serviceType; |
| primingProxyRecord->iService = serviceId; |
| primingProxyRecord->iUseProxyServer = ETrue; |
| |
| proxyRecords->iRecords.AppendL(primingProxyRecord); |
| // Ownership of primingProxyRecord is transferred to |
| // proxyRecords, just remove it from the CleanupStack |
| CleanupStack::Pop(primingProxyRecord); |
| return proxyRecords; |
| } |
| |
| QList<QNetworkProxy> SymbianProxyQuery::proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query) |
| { |
| QList<QNetworkProxy> foundProxies; |
| if (query.queryType() != QNetworkProxyQuery::UrlRequest) { |
| return foundProxies; |
| } |
| |
| CMDBSession *iDb = CMDBSession::NewLC(KCDVersion1_1); |
| CCDIAPRecord *iap = getIapRecordLC(aIAPId, *iDb); |
| |
| // Read service table id and service type |
| // from the IAP record found |
| TUint32 serviceId = iap->iService; |
| RBuf serviceType; |
| serviceType.CreateL(iap->iServiceType); |
| CleanupStack::PopAndDestroy(iap); |
| CleanupClosePushL(serviceType); |
| |
| CMDBRecordSet<CCDProxiesRecord> *proxyRecords = prepareQueryLC(serviceId, serviceType); |
| |
| // Now to find a proxy table matching our criteria |
| if (proxyRecords->FindL(*iDb)) { |
| TInt count = proxyRecords->iRecords.Count(); |
| for(TInt index = 0; index < count; index++) { |
| CCDProxiesRecord *proxyRecord = static_cast<CCDProxiesRecord *> (proxyRecords->iRecords[index]); |
| RBuf serverName; |
| serverName.CreateL(proxyRecord->iServerName); |
| CleanupClosePushL(serverName); |
| if (serverName.Length() == 0) |
| User::Leave(KErrNotFound); |
| QString serverNameQt((const QChar*)serverName.Ptr(), serverName.Length()); |
| CleanupStack::Pop(); // serverName |
| TUint32 port = proxyRecord->iPortNumber; |
| |
| QNetworkProxy proxy(QNetworkProxy::HttpProxy, serverNameQt, port); |
| foundProxies.append(proxy); |
| } |
| } |
| |
| CleanupStack::PopAndDestroy(proxyRecords); |
| CleanupStack::Pop(); // serviceType |
| CleanupStack::PopAndDestroy(iDb); |
| |
| return foundProxies; |
| } |
| |
| QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query) |
| { |
| QList<QNetworkProxy> proxies; |
| SymbianIapId iapId; |
| TInt error; |
| QNetworkConfigurationManager manager; |
| iapId = SymbianProxyQuery::getIapId(manager); |
| if (iapId.isValid()) { |
| TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query)) |
| if (error != KErrNone) { |
| qWarning() << "Error while retrieving proxies: '" << error << '"'; |
| proxies.clear(); |
| } |
| } |
| proxies << QNetworkProxy::NoProxy; |
| |
| return proxies; |
| } |
| |
| QT_END_NAMESPACE |
| |
| #endif |