diff options
Diffstat (limited to 'src/network/kernel/qhostinfo_symbian.cpp')
-rw-r--r-- | src/network/kernel/qhostinfo_symbian.cpp | 600 |
1 files changed, 0 insertions, 600 deletions
diff --git a/src/network/kernel/qhostinfo_symbian.cpp b/src/network/kernel/qhostinfo_symbian.cpp deleted file mode 100644 index 042899d9a4..0000000000 --- a/src/network/kernel/qhostinfo_symbian.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtNetwork 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$ -** -****************************************************************************/ - -//#define QHOSTINFO_DEBUG - -// Qt Headers -#include <QByteArray> -#include <QUrl> -#include <QList> - -#include "qplatformdefs.h" - -#include "qhostinfo_p.h" -#include <private/qcore_symbian_p.h> -#include <private/qsystemerror_p.h> -#include <private/qnetworksession_p.h> - -// Header does not exist in the S60 5.0 SDK -//#include <networking/dnd_err.h> -const TInt KErrDndNameNotFound = -5120; // Returned when no data found for GetByName -const TInt KErrDndAddrNotFound = -5121; // Returned when no data found for GetByAddr - -QT_BEGIN_NAMESPACE - -static void setError_helper(QHostInfo &info, TInt symbianError) -{ - switch (symbianError) { - case KErrDndNameNotFound: - case KErrDndAddrNotFound: - case KErrNotFound: - case KErrEof: - // various "no more results" error codes - info.setError(QHostInfo::HostNotFound); - info.setErrorString(QObject::tr("Host not found")); - break; - default: - // Unknown error - info.setError(QHostInfo::UnknownError); - info.setErrorString(QSystemError(symbianError, QSystemError::NativeError).toString()); - break; - } -} - -QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetworkSession> networkSession) -{ - QHostInfo results; - - // Connect to ESOCK - RSocketServ socketServ(qt_symbianGetSocketServer()); - RHostResolver hostResolver; - - - int err; - if (networkSession) - err = QNetworkSessionPrivate::nativeOpenHostResolver(*networkSession, hostResolver, KAfInet, KProtocolInetUdp); - else - err = hostResolver.Open(socketServ, KAfInet, KProtocolInetUdp); - if (err) { - setError_helper(results, err); - return results; - } - - TNameEntry nameResult; - -#if defined(QHOSTINFO_DEBUG) - qDebug("QHostInfoAgent::fromName(%s) looking up...", - hostName.toLatin1().constData()); -#endif - - QHostAddress address; - if (address.setAddress(hostName)) { - // Reverse lookup -#if defined(QHOSTINFO_DEBUG) - qDebug("(reverse lookup)"); -#endif - TInetAddr IpAdd; - IpAdd.Input(qt_QString2TPtrC(hostName)); - - // Synchronous request. nameResult returns Host Name. - err = hostResolver.GetByAddress(IpAdd, nameResult); - if (err) { - //for behavioural compatibility with Qt 4.7 and unix/windows - //backends: don't report error, return ip address as host name - results.setHostName(address.toString()); - } else { - results.setHostName(qt_TDesC2QString(nameResult().iName)); - } - results.setAddresses(QList<QHostAddress>() << address); - return results; - } - - // IDN support - QByteArray aceHostname = QUrl::toAce(hostName); - results.setHostName(hostName); - if (aceHostname.isEmpty()) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(hostName.isEmpty() ? - QCoreApplication::translate("QHostInfoAgent", "No host name given") : - QCoreApplication::translate("QHostInfoAgent", "Invalid hostname")); - return results; - } - - - // Call RHostResolver::GetByAddress, and place all IPv4 addresses at the start and - // the IPv6 addresses at the end of the address list in results. - - // Synchronous request. - err = hostResolver.GetByName(qt_QString2TPtrC(QString::fromLatin1(aceHostname)), nameResult); - if (err) { - setError_helper(results, err); - return results; - } - - QList<QHostAddress> hostAddresses; - - TInetAddr hostAdd = nameResult().iAddr; - // 39 is the maximum length of an IPv6 address. - TBuf<39> ipAddr; - - // Fill ipAddr with the IP address from hostAdd - hostAdd.Output(ipAddr); - if (ipAddr.Length() > 0) - hostAddresses.append(QHostAddress(qt_TDesC2QString(ipAddr))); - - // Check if there's more than one IP address linkd to this name - while (hostResolver.Next(nameResult) == KErrNone) { - hostAdd = nameResult().iAddr; - hostAdd.Output(ipAddr); - - // Ensure that record is valid (not an alias and with length greater than 0) - if (!(nameResult().iFlags & TNameRecord::EAlias) && !(hostAdd.IsUnspecified())) { - hostAddresses.append(QHostAddress(qt_TDesC2QString(ipAddr))); - } - } - - hostResolver.Close(); - - results.setAddresses(hostAddresses); - return results; -} - -QHostInfo QHostInfoAgent::fromName(const QString &hostName) -{ - // null shared pointer - QSharedPointer<QNetworkSession> networkSession; - return fromName(hostName, networkSession); -} - -QString QHostInfo::localHostName() -{ - // Connect to ESOCK - RSocketServ socketServ(qt_symbianGetSocketServer()); - RHostResolver hostResolver; - - // RConnection not required to get the host name - int err = hostResolver.Open(socketServ, KAfInet, KProtocolInetUdp); - if (err) - return QString(); - - THostName hostName; - err = hostResolver.GetHostName(hostName); - if (err) - return QString(); - - hostResolver.Close(); - - return qt_TDesC2QString(hostName); -} - -QString QHostInfo::localDomainName() -{ - // This concept does not exist on Symbian OS because the device can be on - // multiple networks with multiple "local domain" names. - // For now, return a null string. - return QString(); -} - - -QSymbianHostResolver::QSymbianHostResolver(const QString &hostName, int identifier, QSharedPointer<QNetworkSession> networkSession) - : CActive(CActive::EPriorityStandard), iHostName(hostName), - iSocketServ(qt_symbianGetSocketServer()), iNetworkSession(networkSession), iResults(identifier) -{ - CActiveScheduler::Add(this); -} - -QSymbianHostResolver::~QSymbianHostResolver() -{ -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostInfoLookupManager::~QSymbianHostResolver" << id(); -#endif - Cancel(); - iHostResolver.Close(); -} - -// Async equivalent to QHostInfoAgent::fromName() -void QSymbianHostResolver::requestHostLookup() -{ - -#if defined(QHOSTINFO_DEBUG) - qDebug("QSymbianHostResolver::requestHostLookup(%s) looking up... (id = %d)", - iHostName.toLatin1().constData(), id()); -#endif - - QSymbianHostInfoLookupManager *manager = QSymbianHostInfoLookupManager::globalInstance(); - if (manager->cache.isEnabled()) { - //check if name has been put in the cache while this request was queued - bool valid; - QHostInfo cachedResult = manager->cache.get(iHostName, &valid); - if (valid) { -#if defined(QHOSTINFO_DEBUG) - qDebug("...found in cache"); -#endif - iResults = cachedResult; - iState = ECompleteFromCache; - SetActive(); - TRequestStatus* stat = &iStatus; - User::RequestComplete(stat, KErrNone); - return; - } - } - - int err; - if (iNetworkSession) { - err = QNetworkSessionPrivate::nativeOpenHostResolver(*iNetworkSession, iHostResolver, KAfInet, KProtocolInetUdp); -#if defined(QHOSTINFO_DEBUG) - qDebug("using resolver from session (err = %d)", err); -#endif - } else { - err = iHostResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp); -#if defined(QHOSTINFO_DEBUG) - qDebug("using default resolver (err = %d)", err); -#endif - } - if (err) { - setError_helper(iResults, err); - } else { - - if (iAddress.setAddress(iHostName)) { - // Reverse lookup - IpAdd.Input(qt_QString2TPtrC(iHostName)); - - // Asynchronous request. - iHostResolver.GetByAddress(IpAdd, iNameResult, iStatus); // <---- ASYNC - iState = EGetByAddress; - - } else { - - // IDN support - QByteArray aceHostname = QUrl::toAce(iHostName); - iResults.setHostName(iHostName); - if (aceHostname.isEmpty()) { - iResults.setError(QHostInfo::HostNotFound); - iResults.setErrorString(iHostName.isEmpty() ? - QCoreApplication::translate("QHostInfoAgent", "No host name given") : - QCoreApplication::translate("QHostInfoAgent", "Invalid hostname")); - - err = KErrArgument; - } else { - iEncodedHostName = QString::fromLatin1(aceHostname); - iHostNamePtr.Set(qt_QString2TPtrC(iEncodedHostName)); - - // Asynchronous request. - iHostResolver.GetByName(iHostNamePtr, iNameResult, iStatus); - iState = EGetByName; - } - } - } - SetActive(); - if (err) { - iHostResolver.Close(); - - //self complete so that RunL can inform manager without causing recursion - iState = EError; - TRequestStatus* stat = &iStatus; - User::RequestComplete(stat, err); - } -} - -void QSymbianHostResolver::abortHostLookup() -{ - if (resultEmitter.thread() == QThread::currentThread()) { -#ifdef QHOSTINFO_DEBUG - qDebug("QSymbianHostResolver::abortHostLookup - deleting %d", id()); -#endif - //normal case, abort from same thread it was started - delete this; //will cancel outstanding request - } else { -#ifdef QHOSTINFO_DEBUG - qDebug("QSymbianHostResolver::abortHostLookup - detaching %d", id()); -#endif - //abort from different thread, carry on but don't report the results - resultEmitter.disconnect(); - } -} - -void QSymbianHostResolver::DoCancel() -{ -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostResolver::DoCancel" << QThread::currentThreadId() << id() << (int)iState << this; -#endif - if (iState == EGetByAddress || iState == EGetByName) { - //these states have made an async request to host resolver - iHostResolver.Cancel(); - } else { - //for the self completing states there is nothing to cancel - Q_ASSERT(iState == EError || iState == ECompleteFromCache); - } -} - -void QSymbianHostResolver::RunL() -{ - QT_TRYCATCH_LEAVING(run()); -} - -void QSymbianHostResolver::run() -{ - switch (iState) { - case EGetByName: - processNameResult(); - break; - case EGetByAddress: - processAddressResult(); - break; - case ECompleteFromCache: - case EError: - returnResults(); - break; - default: - qWarning("QSymbianHostResolver internal error, bad state in run()"); - iResults.setError(QHostInfo::UnknownError); - iResults.setErrorString(QSystemError(KErrCorrupt,QSystemError::NativeError).toString()); - returnResults(); - } -} - -void QSymbianHostResolver::returnResults() -{ -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostResolver::returnResults" << iResults.error() << iResults.errorString(); - foreach (QHostAddress addr, iResults.addresses()) - qDebug() << addr; -#endif - iState = EIdle; - - QSymbianHostInfoLookupManager *manager = QSymbianHostInfoLookupManager::globalInstance(); - if (manager->cache.isEnabled()) { - manager->cache.put(iHostName, iResults); - } - manager->lookupFinished(this); - - resultEmitter.emitResultsReady(iResults); - - delete this; -} - -TInt QSymbianHostResolver::RunError(TInt aError) -{ - QT_TRY { - iState = EIdle; - - QSymbianHostInfoLookupManager *manager = QSymbianHostInfoLookupManager::globalInstance(); - manager->lookupFinished(this); - - setError_helper(iResults, aError); - - resultEmitter.emitResultsReady(iResults); - } - QT_CATCH(...) {} - - delete this; - - return KErrNone; -} - -void QSymbianHostResolver::processNameResult() -{ - if (iStatus.Int() == KErrNone) { - TInetAddr hostAdd = iNameResult().iAddr; - // 39 is the maximum length of an IPv6 address. - TBuf<39> ipAddr; - - hostAdd.Output(ipAddr); - - // Ensure that record is valid (not an alias and with length greater than 0) - if (!(iNameResult().iFlags & TNameRecord::EAlias) && !(hostAdd.IsUnspecified())) { - iHostAddresses.append(QHostAddress(qt_TDesC2QString(ipAddr))); - } - - iState = EGetByName; - iHostResolver.Next(iNameResult, iStatus); - SetActive(); - } - else { - // No more addresses, so return the results (or an error if there aren't any). -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostResolver::processNameResult with err=" << iStatus.Int() << "count=" << iHostAddresses.count(); -#endif - if (iHostAddresses.count() > 0) { - iResults.setAddresses(iHostAddresses); - } else { - iState = EError; - setError_helper(iResults, iStatus.Int()); - } - returnResults(); - } -} - -void QSymbianHostResolver::processAddressResult() -{ - TInt err = iStatus.Int(); - - if (err < 0) { - //For behavioural compatibility with Qt 4.7, don't report errors on reverse lookup, - //return the address as a string (same as unix/windows backends) - iResults.setHostName(iAddress.toString()); - } else { - iResults.setHostName(qt_TDesC2QString(iNameResult().iName)); - } - iResults.setAddresses(QList<QHostAddress>() << iAddress); - returnResults(); -} - - -int QSymbianHostResolver::id() -{ - return iResults.lookupId(); -} - -QSymbianHostInfoLookupManager::QSymbianHostInfoLookupManager() -{ -} - -QSymbianHostInfoLookupManager::~QSymbianHostInfoLookupManager() -{ -} - -void QSymbianHostInfoLookupManager::clear() -{ - QMutexLocker locker(&mutex); -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostInfoLookupManager::clear" << QThread::currentThreadId(); -#endif - foreach (QSymbianHostResolver *hr, iCurrentLookups) - hr->abortHostLookup(); - iCurrentLookups.clear(); - qDeleteAll(iScheduledLookups); - cache.clear(); -} - -void QSymbianHostInfoLookupManager::lookupFinished(QSymbianHostResolver *r) -{ - QMutexLocker locker(&mutex); - -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostInfoLookupManager::lookupFinished" << QThread::currentThreadId() << r->id() << "current" << iCurrentLookups.count() << "queued" << iScheduledLookups.count(); -#endif - // remove finished lookup from array and destroy - TInt count = iCurrentLookups.count(); - for (TInt i = 0; i < count; i++) { - if (iCurrentLookups[i]->id() == r->id()) { - iCurrentLookups.removeAt(i); - break; - } - } - - runNextLookup(); -} - -void QSymbianHostInfoLookupManager::runNextLookup() -{ -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostInfoLookupManager::runNextLookup" << QThread::currentThreadId() << "current" << iCurrentLookups.count() << "queued" << iScheduledLookups.count(); -#endif - // check to see if there are any scheduled lookups - for (int i=0; i<iScheduledLookups.count(); i++) { - QSymbianHostResolver* hostResolver = iScheduledLookups.at(i); - if (hostResolver->resultEmitter.thread() == QThread::currentThread()) { - // if so, move one to the current lookups and run it - iCurrentLookups.append(hostResolver); - iScheduledLookups.removeAt(i); - hostResolver->requestHostLookup(); - // if spare capacity, try to start another one - if (iCurrentLookups.count() >= KMaxConcurrentLookups) - break; - i--; //compensate for removeAt - } - } -} - -// called from QHostInfo -void QSymbianHostInfoLookupManager::scheduleLookup(QSymbianHostResolver* r) -{ - QMutexLocker locker(&mutex); - -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostInfoLookupManager::scheduleLookup" << QThread::currentThreadId() << r->id() << "current" << iCurrentLookups.count() << "queued" << iScheduledLookups.count(); -#endif - // Check to see if we have space on the current lookups pool. - bool defer = false; - if (iCurrentLookups.count() >= KMaxConcurrentLookups) { - // busy, defer unless there are no request in this thread - // at least one active request per thread with queued requests is needed - for (int i=0; i < iCurrentLookups.count();i++) { - if (iCurrentLookups.at(i)->resultEmitter.thread() == QThread::currentThread()) { - defer = true; - break; - } - } - } - if (defer) { - // If no, schedule for later. - iScheduledLookups.append(r); -#if defined(QHOSTINFO_DEBUG) - qDebug(" - scheduled"); -#endif - return; - } else { - // If yes, add it to the current lookups. - iCurrentLookups.append(r); - - // ... and trigger the async call. - r->requestHostLookup(); - } -} - -void QSymbianHostInfoLookupManager::abortLookup(int id) -{ - QMutexLocker locker(&mutex); - -#if defined(QHOSTINFO_DEBUG) - qDebug() << "QSymbianHostInfoLookupManager::abortLookup" << QThread::currentThreadId() << id << "current" << iCurrentLookups.count() << "queued" << iScheduledLookups.count(); -#endif - int i = 0; - // Find the aborted lookup by ID. - // First in the current lookups. - for (i = 0; i < iCurrentLookups.count(); i++) { - if (id == iCurrentLookups[i]->id()) { - QSymbianHostResolver* r = iCurrentLookups.at(i); - iCurrentLookups.removeAt(i); - r->abortHostLookup(); - runNextLookup(); - return; - } - } - // Then in the scheduled lookups. - for (i = 0; i < iScheduledLookups.count(); i++) { - if (id == iScheduledLookups[i]->id()) { - QSymbianHostResolver* r = iScheduledLookups.at(i); - iScheduledLookups.removeAt(i); - delete r; - return; - } - } -} - -QSymbianHostInfoLookupManager* QSymbianHostInfoLookupManager::globalInstance() -{ - return static_cast<QSymbianHostInfoLookupManager*> - (QAbstractHostInfoLookupManager::globalInstance()); -} - -QT_END_NAMESPACE |