/****************************************************************************
**
** 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 plugins 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$
**
****************************************************************************/

#include "symbianengine.h"
#include "qnetworksession_impl.h"

#include <commdb.h>
#include <cdbcols.h>
#include <d32dbms.h>
#include <nifvar.h>
#include <QTimer>
#include <QTime>  // For randgen seeding
#include <QtCore> // For randgen seeding


#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
#include <QDebug>
#endif

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    #include <cmdestination.h>
    #include <cmconnectionmethod.h>
    #include <cmconnectionmethoddef.h>
    #include <cmpluginwlandef.h>
    #include <cmpluginpacketdatadef.h>
    #include <cmplugindialcommondefs.h>
#else
    #include <ApAccessPointItem.h>
    #include <ApDataHandler.h>
    #include <ApUtils.h>
#endif

#ifndef QT_NO_BEARERMANAGEMENT

QT_BEGIN_NAMESPACE

static const int KUserChoiceIAPId = 0;

SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate()
:   numericId(0), connectionId(0)
{
}

SymbianNetworkConfigurationPrivate::~SymbianNetworkConfigurationPrivate()
{
}

SymbianEngine::SymbianEngine(QObject *parent)
:   QBearerEngine(parent), CActive(CActive::EPriorityHigh), iFirstUpdate(true), ipCommsDB(0),
    iInitOk(true), iUpdatePending(false), ipAccessPointsAvailabilityScanner(0)
{
}

void SymbianEngine::initialize()
{
    QMutexLocker locker(&mutex);

    CActiveScheduler::Add(this);

    // Seed the randomgenerator
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid());

    TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP));
    if (error != KErrNone) {
        iInitOk = false;
        return;
    }

    TRAP(error, StartConnectionMonitorNotifyL());
    if (error != KErrNone) {
        iInitOk = false;
        return;
    }

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    TRAP(error, iCmManager.OpenL());
    if (error != KErrNone) {
        iInitOk = false;
        return;
    }
#endif

    SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
    cpPriv->name = "UserChoice";
    cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
    cpPriv->state = QNetworkConfiguration::Discovered;
    cpPriv->isValid = true;
    cpPriv->id = QString::number(qHash(KUserChoiceIAPId));
    cpPriv->numericId = KUserChoiceIAPId;
    cpPriv->connectionId = 0;
    cpPriv->type = QNetworkConfiguration::UserChoice;
    cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
    cpPriv->roamingSupported = false;

    QNetworkConfigurationPrivatePointer ptr(cpPriv);
    userChoiceConfigurations.insert(ptr->id, ptr);

    updateConfigurations();
    updateStatesToSnaps();
    updateAvailableAccessPoints(); // On first time updates (without WLAN scans)
    // Start monitoring IAP and/or SNAP changes in Symbian CommsDB
    startCommsDatabaseNotifications();
}

void SymbianEngine::StartConnectionMonitorNotifyL()
{
    iConnectionMonitor.ConnectL();
    CleanupClosePushL(iConnectionMonitor);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    User::LeaveIfError(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1));
#endif
    iConnectionMonitor.NotifyEventL(*this);
    CleanupStack::Pop();
}

SymbianEngine::~SymbianEngine()
{
    Cancel();

    //The scanner may be using the connection monitor so it needs to be
    //deleted first while the handle is still valid.
    delete ipAccessPointsAvailabilityScanner;

    iConnectionMonitor.CancelNotifications();
    iConnectionMonitor.Close();

    // CCommsDatabase destructor and RCmManager.Close() use cleanup stack. Since QNetworkConfigurationManager
    // is a global static, but the time we are here, E32Main() has been exited already and
    // the thread's default cleanup stack has been deleted. Without this line, a
    // 'E32USER-CBase 69' -panic will occur.
    CTrapCleanup* cleanup = CTrapCleanup::New();
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    iCmManager.Close();
#endif
    delete ipCommsDB;
    delete cleanup;
}

void SymbianEngine::delayedConfigurationUpdate()
{
    QMutexLocker locker(&mutex);

    if (iUpdatePending) {
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
        qDebug("QNCM delayed configuration update (ECommit or ERecover occurred).");
#endif
        TRAPD(error, updateConfigurationsL());
        if (error == KErrNone) {
            updateStatesToSnaps();
        }
        iUpdatePending = false;
        // Start monitoring again.
        if (!IsActive()) {
            SetActive();
            // Start waiting for new notification
            ipCommsDB->RequestNotification(iStatus);
        }
    }
}

bool SymbianEngine::hasIdentifier(const QString &id)
{
    QMutexLocker locker(&mutex);

    return accessPointConfigurations.contains(id) ||
           snapConfigurations.contains(id) ||
           userChoiceConfigurations.contains(id);
}

QNetworkConfigurationManager::Capabilities SymbianEngine::capabilities() const
{
    QNetworkConfigurationManager::Capabilities capFlags;

    capFlags = QNetworkConfigurationManager::CanStartAndStopInterfaces |
               QNetworkConfigurationManager::DirectConnectionRouting |
               QNetworkConfigurationManager::SystemSessionSupport |
               QNetworkConfigurationManager::DataStatistics |
               QNetworkConfigurationManager::NetworkSessionRequired;

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    capFlags |= QNetworkConfigurationManager::ApplicationLevelRoaming |
                QNetworkConfigurationManager::ForcedRoaming;
#endif

    return capFlags;
}

QNetworkSessionPrivate *SymbianEngine::createSessionBackend()
{
    return new QNetworkSessionPrivateImpl(this);
}

void SymbianEngine::requestUpdate()
{
    QMutexLocker locker(&mutex);

    if (!iInitOk || iUpdateGoingOn) {
        return;
    }
    iUpdateGoingOn = true;

    stopCommsDatabaseNotifications();
    updateConfigurations(); // Synchronous call
    updateAvailableAccessPoints(); // Asynchronous call
}

void SymbianEngine::updateConfigurations()
{
    if (!iInitOk)
        return;

    TRAP_IGNORE(updateConfigurationsL());
}

void SymbianEngine::updateConfigurationsL()
{
    QList<QString> knownConfigs = accessPointConfigurations.keys();
    QList<QString> knownSnapConfigs = snapConfigurations.keys();

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    // S60 version is >= Series60 3rd Edition Feature Pack 2
    TInt error = KErrNone;
    
    // Loop through all IAPs
    RArray<TUint32> connectionMethods; // IAPs
    CleanupClosePushL(connectionMethods);
    iCmManager.ConnectionMethodL(connectionMethods);
    for(int i = 0; i < connectionMethods.Count(); i++) {
        RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]);
        CleanupClosePushL(connectionMethod);
        TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
        QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
        if (accessPointConfigurations.contains(ident)) {
            knownConfigs.removeOne(ident);
        } else {
            SymbianNetworkConfigurationPrivate* cpPriv = NULL;
            TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod));
            if (error == KErrNone) {
                QNetworkConfigurationPrivatePointer ptr(cpPriv);
                accessPointConfigurations.insert(ptr->id, ptr);
                if (!iFirstUpdate) {
                    // Emit configuration added. Connected slots may throw execptions
                    // which propagate here --> must be converted to leaves (standard
                    // std::exception would cause any TRAP trapping this function to terminate
                    // program).
                    QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
                    updateStatesToSnaps();
                    mutex.unlock();
                    QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
                    mutex.lock();
                }
            }
        }
        CleanupStack::PopAndDestroy(&connectionMethod);
    }
    CleanupStack::PopAndDestroy(&connectionMethods);
    
    // Loop through all SNAPs
    RArray<TUint32> destinations;
    CleanupClosePushL(destinations);
    iCmManager.AllDestinationsL(destinations);
    for(int i = 0; i < destinations.Count(); i++) {
        RCmDestination destination;

        // Some destinatsions require ReadDeviceData -capability (MMS/WAP)
        // The below function will leave in these cases. Don't. Proceed to
        // next destination (if any).
        TRAPD(error, destination = iCmManager.DestinationL(destinations[i]));
        if (error == KErrPermissionDenied) {
            continue;
        } else {
            User::LeaveIfError(error);
        }

        CleanupClosePushL(destination);
        QString ident = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX +
                        QString::number(qHash(destination.Id()));
        if (snapConfigurations.contains(ident)) {
            knownSnapConfigs.removeOne(ident);
        } else {
            SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;

            HBufC *pName = destination.NameLC();
            QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
            CleanupStack::PopAndDestroy(pName);
            pName = NULL;

            cpPriv->isValid = true;
            cpPriv->id = ident;
            cpPriv->numericId = destination.Id();
            cpPriv->connectionId = 0;
            cpPriv->state = QNetworkConfiguration::Defined;
            cpPriv->type = QNetworkConfiguration::ServiceNetwork;
            cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
            cpPriv->roamingSupported = false;

            QNetworkConfigurationPrivatePointer ptr(cpPriv);
            snapConfigurations.insert(ident, ptr);
            if (!iFirstUpdate) {
                QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
                updateStatesToSnaps();
                mutex.unlock();
                QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
                mutex.lock();
            }
        }

        // Loop through all connection methods in this SNAP
        QMap<unsigned int, QNetworkConfigurationPrivatePointer> connections;
        for (int j=0; j < destination.ConnectionMethodCount(); j++) {
            RCmConnectionMethod connectionMethod = destination.ConnectionMethodL(j);
            CleanupClosePushL(connectionMethod);

            TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
            QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
            // Check that IAP can be found from accessPointConfigurations list
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
            if (!ptr) {
                SymbianNetworkConfigurationPrivate *cpPriv = NULL;
                TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod));
                if (error == KErrNone) {
                    ptr = QNetworkConfigurationPrivatePointer(cpPriv);
                    accessPointConfigurations.insert(ptr->id, ptr);

                    if (!iFirstUpdate) {
                        QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
                        updateStatesToSnaps();
                        mutex.unlock();
                        QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
                        mutex.lock();
                    }
                }
            } else {
                knownConfigs.removeOne(iface);
            }

            if (ptr) {
                unsigned int priority;
                TRAPD(error, priority = destination.PriorityL(connectionMethod));
                if (!error)
                    connections.insert(priority, ptr);
            }

            CleanupStack::PopAndDestroy(&connectionMethod);
        }

        QNetworkConfigurationPrivatePointer privSNAP = snapConfigurations.value(ident);
        QMutexLocker snapConfigLocker(&privSNAP->mutex);

        if (privSNAP->serviceNetworkMembers != connections) {
            privSNAP->serviceNetworkMembers = connections;

            // Roaming is supported only if SNAP contains more than one IAP
            privSNAP->roamingSupported = privSNAP->serviceNetworkMembers.count() > 1;

            snapConfigLocker.unlock();

            updateStatesToSnaps();

            mutex.unlock();
            QT_TRYCATCH_LEAVING(emit configurationChanged(privSNAP));
            mutex.lock();
        }

        CleanupStack::PopAndDestroy(&destination);
    }
    CleanupStack::PopAndDestroy(&destinations);
#else
    // S60 version is < Series60 3rd Edition Feature Pack 2
    CCommsDbTableView* pDbTView = ipCommsDB->OpenTableLC(TPtrC(IAP));

    // Loop through all IAPs
    TUint32 apId = 0;
    TInt retVal = pDbTView->GotoFirstRecord();
    while (retVal == KErrNone) {
        pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId);
        QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
        if (accessPointConfigurations.contains(ident)) {
            knownConfigs.removeOne(ident);
        } else {
            SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
            if (readNetworkConfigurationValuesFromCommsDb(apId, cpPriv)) {
                QNetworkConfigurationPrivatePointer ptr(cpPriv);
                accessPointConfigurations.insert(ident, ptr);
                if (!iFirstUpdate) {
                    QT_TRYCATCH_LEAVING(updateActiveAccessPoints());
                    updateStatesToSnaps();
                    mutex.unlock();
                    QT_TRYCATCH_LEAVING(emit configurationAdded(ptr));
                    mutex.lock();
                }
            } else {
                delete cpPriv;
            }
        }
        retVal = pDbTView->GotoNextRecord();
    }
    CleanupStack::PopAndDestroy(pDbTView);
#endif

    QT_TRYCATCH_LEAVING(updateActiveAccessPoints());

    foreach (const QString &oldIface, knownConfigs) {
        //remove non existing IAP
        QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface);

        mutex.unlock();
        emit configurationRemoved(ptr);
        QT_TRYCATCH_LEAVING(emit configurationRemoved(ptr));
        mutex.lock();

        // Remove non existing IAP from SNAPs
        foreach (const QString &iface, snapConfigurations.keys()) {
            QNetworkConfigurationPrivatePointer ptr2 = snapConfigurations.value(iface);
            // => Check if one of the IAPs of the SNAP is active
            QMutexLocker snapConfigLocker(&ptr2->mutex);
            QMutableMapIterator<unsigned int, QNetworkConfigurationPrivatePointer> i(ptr2->serviceNetworkMembers);
            while (i.hasNext()) {
                i.next();

                if (toSymbianConfig(i.value())->numericIdentifier() ==
                    toSymbianConfig(ptr)->numericIdentifier()) {
                    i.remove();
                    break;
                }
            }
        }    
    }

    foreach (const QString &oldIface, knownSnapConfigs) {
        //remove non existing SNAPs
        QNetworkConfigurationPrivatePointer ptr = snapConfigurations.take(oldIface);

        mutex.unlock();
        emit configurationRemoved(ptr);
        QT_TRYCATCH_LEAVING(emit configurationRemoved(ptr));
        mutex.lock();
    }

    // find default configuration.
    stopCommsDatabaseNotifications();
    TRAP_IGNORE(defaultConfig = defaultConfigurationL());
    startCommsDatabaseNotifications();

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    updateStatesToSnaps();
#endif
}

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL(
        RCmConnectionMethod& connectionMethod)
{
    SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate;
    TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId);
    QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId));
    
    HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName);
    CleanupStack::PushL(pName);
    QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()));
    CleanupStack::PopAndDestroy(pName);
    pName = NULL;
    
    TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType);
    switch (bearerId) {
    case KCommDbBearerCSD:
        cpPriv->bearerType = QNetworkConfiguration::Bearer2G;
        break;
    case KCommDbBearerWcdma:
        cpPriv->bearerType = QNetworkConfiguration::BearerWCDMA;
        break;
    case KCommDbBearerLAN:
        cpPriv->bearerType = QNetworkConfiguration::BearerEthernet;
        break;
    case KCommDbBearerVirtual:
        cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
        break;
    case KCommDbBearerPAN:
        cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
        break;
    case KCommDbBearerWLAN:
        cpPriv->bearerType = QNetworkConfiguration::BearerWLAN;
        break;
    default:
        cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
        break;
    }
    
    TInt error = KErrNone;
    TUint32 bearerType = connectionMethod.GetIntAttributeL(CMManager::ECmBearerType);
    switch (bearerType) {
    case KUidPacketDataBearerType:
        // "Packet data" Bearer => Mapping is done using "Access point name"
        TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EPacketDataAPName));
        break;
    case KUidWlanBearerType:
        // "Wireless LAN" Bearer => Mapping is done using "WLAN network name" = SSID
        TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EWlanSSID));
        break;
    }
    if (!pName) {
        // "Data call" Bearer or "High Speed (GSM)" Bearer => Mapping is done using "Dial-up number"
        TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EDialDefaultTelNum));
    }

    if (error == KErrNone && pName) {
        CleanupStack::PushL(pName);
        QT_TRYCATCH_LEAVING(cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length()));
        CleanupStack::PopAndDestroy(pName);
        pName = NULL;
    }
 
    cpPriv->state = QNetworkConfiguration::Defined;
    TBool isConnected = connectionMethod.GetBoolAttributeL(CMManager::ECmConnected);
    if (isConnected) {
        cpPriv->state = QNetworkConfiguration::Active;
    }
    
    cpPriv->isValid = true;
    cpPriv->id = ident;
    cpPriv->numericId = iapId;
    cpPriv->connectionId = 0;
    cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
    cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
    cpPriv->roamingSupported = false;
    return cpPriv;
}
#else
bool SymbianEngine::readNetworkConfigurationValuesFromCommsDb(
        TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration)
{
    TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration));
    if (error != KErrNone) {
        return false;        
    }
    return true;
}

void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL(
        TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration)
{
    CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB); 
    CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC(); 
    TBuf<KCommsDbSvrMaxColumnNameLength> name;
    
    CApUtils* pApUtils = CApUtils::NewLC(*ipCommsDB);
    TUint32 apId = pApUtils->WapIdFromIapIdL(aApId);
    
    pDataHandler->AccessPointDataL(apId,*pAPItem);
    pAPItem->ReadTextL(EApIapName, name);
    if (name.Compare(_L("Easy WLAN")) == 0) {
        // "Easy WLAN" won't be accepted to the Configurations list
        User::Leave(KErrNotFound);
    }
    
    QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(aApId));
    
    QT_TRYCATCH_LEAVING(apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length()));
    apNetworkConfiguration->isValid = true;
    apNetworkConfiguration->id = ident;
    apNetworkConfiguration->numericId = aApId;
    apNetworkConfiguration->connectionId = 0;
    apNetworkConfiguration->state = (QNetworkConfiguration::Defined);
    apNetworkConfiguration->type = QNetworkConfiguration::InternetAccessPoint;
    apNetworkConfiguration->purpose = QNetworkConfiguration::UnknownPurpose;
    apNetworkConfiguration->roamingSupported = false;
    switch (pAPItem->BearerTypeL()) {
    case EApBearerTypeCSD:      
        apNetworkConfiguration->bearerType = QNetworkConfiguration::Bearer2G;
        break;
    case EApBearerTypeGPRS:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::Bearer2G;
        break;
    case EApBearerTypeHSCSD:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerHSPA;
        break;
    case EApBearerTypeCDMA:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerCDMA2000;
        break;
    case EApBearerTypeWLAN:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerWLAN;
        break;
    case EApBearerTypeLAN:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerEthernet;
        break;
    case EApBearerTypeLANModem:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerEthernet;
        break;
    default:
        apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerUnknown;
        break;
    }
    
    CleanupStack::PopAndDestroy(pApUtils);
    CleanupStack::PopAndDestroy(pAPItem);
    CleanupStack::PopAndDestroy(pDataHandler);
}
#endif

QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfiguration()
{
    QMutexLocker locker(&mutex);

    return defaultConfig;
}

QStringList SymbianEngine::accessPointConfigurationIdentifiers()
{
    QMutexLocker locker(&mutex);

    return accessPointConfigurations.keys();
}

QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL()
{
    QNetworkConfigurationPrivatePointer ptr;

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    // Check Default Connection (SNAP or IAP)
    TCmDefConnValue defaultConnectionValue;
    iCmManager.ReadDefConnL(defaultConnectionValue);
    if (defaultConnectionValue.iType == ECmDefConnDestination) {
        QString iface = QT_BEARERMGMT_CONFIGURATION_SNAP_PREFIX +
                        QString::number(qHash(defaultConnectionValue.iId));
        ptr = snapConfigurations.value(iface);
    } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) {
        QString iface = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
                        QString::number(qHash(defaultConnectionValue.iId));
        ptr = accessPointConfigurations.value(iface);
    }
#endif
    
    if (ptr) {
        QMutexLocker configLocker(&ptr->mutex);
        if (ptr->isValid)
            return ptr;
    }

    QString iface = QString::number(qHash(KUserChoiceIAPId));
    return userChoiceConfigurations.value(iface);
}

void SymbianEngine::updateActiveAccessPoints()
{
    bool online = false;
    QList<QString> inactiveConfigs = accessPointConfigurations.keys();

    TRequestStatus status;
    TUint connectionCount;
    iConnectionMonitor.GetConnectionCount(connectionCount, status);
    User::WaitForRequest(status);
    
    // Go through all connections and set state of related IAPs to Active.
    // Status needs to be checked carefully, because ConnMon lists also e.g.
    // WLAN connections that are being currently tried --> we don't want to
    // state these as active.
    TUint connectionId;
    TUint subConnectionCount;
    TUint apId;
    TInt connectionStatus;
    if (status.Int() == KErrNone) {
        for (TUint i = 1; i <= connectionCount; i++) {
            iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
            iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
            User::WaitForRequest(status);
            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
            if (!ptr) {
                // If IAP was not found, check if the update was about EasyWLAN
                ptr = configurationFromEasyWlan(apId, connectionId);
                // Change the ident correspondingly
                if (ptr) {
                    ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
                            QString::number(qHash(toSymbianConfig(ptr)->numericIdentifier()));
                }
            }
#endif
            if (ptr) {
                iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
                User::WaitForRequest(status);

                if (connectionStatus == KLinkLayerOpen) {
                    online = true;
                    inactiveConfigs.removeOne(ident);

                    ptr->mutex.lock();
                    toSymbianConfig(ptr)->connectionId = connectionId;
                    ptr->mutex.unlock();

                    // Configuration is Active
                    changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
                }
            }
        }
    }

    // Make sure that state of rest of the IAPs won't be Active
    foreach (const QString &iface, inactiveConfigs) {
        QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
        if (ptr) {
            // Configuration is either Defined or Discovered
            changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered);
        }
    }

    if (iOnline != online) {
        iOnline = online;
        mutex.unlock();
        emit this->onlineStateChanged(online);
        mutex.lock();
    }
}

void SymbianEngine::updateAvailableAccessPoints()
{
    if (!ipAccessPointsAvailabilityScanner) {
        ipAccessPointsAvailabilityScanner = new AccessPointsAvailabilityScanner(*this, iConnectionMonitor);
    }
    if (ipAccessPointsAvailabilityScanner) {
        // Scanning may take a while because WLAN scanning will be done (if device supports WLAN).
        ipAccessPointsAvailabilityScanner->StartScanning();
    }
}

void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo)
{
    iUpdateGoingOn = false;
    if (scanSuccessful) {
        QList<QString> unavailableConfigs = accessPointConfigurations.keys();
        
        // Set state of returned IAPs to Discovered
        // if state is not already Active
        for(TUint i=0; i<iapInfo.iCount; i++) {
            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
                            QString::number(qHash(iapInfo.iIap[i].iIapId));
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
            if (ptr) {
                unavailableConfigs.removeOne(ident);

                QMutexLocker configLocker(&ptr->mutex);
                if (ptr->state < QNetworkConfiguration::Active) {
                    // Configuration is either Discovered or Active
                    changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered);
                }
            }
        }
        
        // Make sure that state of rest of the IAPs won't be Active
        foreach (const QString &iface, unavailableConfigs) {
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
            if (ptr) {
                // Configuration is Defined
                changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered);
            }
        }
    }

    updateStatesToSnaps();
    
    if (!iFirstUpdate) {
        startCommsDatabaseNotifications();
        mutex.unlock();
        emit updateCompleted();
        mutex.lock();
    } else {
        iFirstUpdate = false;
        if (iScanInQueue) {
            iScanInQueue = EFalse;
            updateAvailableAccessPoints();
        }
    }
}

void SymbianEngine::updateStatesToSnaps()
{
    // Go through SNAPs and set correct state to SNAPs
    foreach (const QString &iface, snapConfigurations.keys()) {
        bool discovered = false;
        bool active = false;
        QNetworkConfigurationPrivatePointer ptr = snapConfigurations.value(iface);

        QMutexLocker snapConfigLocker(&ptr->mutex);

        // => Check if one of the IAPs of the SNAP is discovered or active
        //    => If one of IAPs is active, also SNAP is active
        //    => If one of IAPs is discovered but none of the IAPs is active, SNAP is discovered
        QMapIterator<unsigned int, QNetworkConfigurationPrivatePointer> i(ptr->serviceNetworkMembers);
        while (i.hasNext()) {
            i.next();

            const QNetworkConfigurationPrivatePointer child = i.value();

            QMutexLocker configLocker(&child->mutex);

            if ((child->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
                active = true;
                break;
            } else if ((child->state & QNetworkConfiguration::Discovered) ==
                       QNetworkConfiguration::Discovered) {
                discovered = true;
            }
        }
        snapConfigLocker.unlock();
        if (active) {
            changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
        } else if (discovered) {
            changeConfigurationStateTo(ptr, QNetworkConfiguration::Discovered);
        } else {
            changeConfigurationStateTo(ptr, QNetworkConfiguration::Defined);
        }
    }    
}

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
void SymbianEngine::updateMobileBearerToConfigs(TConnMonBearerInfo bearerInfo)
{
    QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i =
        accessPointConfigurations.constBegin();
    while (i != accessPointConfigurations.constEnd()) {
        QNetworkConfigurationPrivatePointer ptr = i.value();

        QMutexLocker locker(&ptr->mutex);

        SymbianNetworkConfigurationPrivate *p = toSymbianConfig(ptr);

        if (p->bearerType >= QNetworkConfiguration::Bearer2G &&
            p->bearerType <= QNetworkConfiguration::BearerHSPA) {
            switch (bearerInfo) {
            case EBearerInfoCSD:
                p->bearerType = QNetworkConfiguration::Bearer2G;
                break;
            case EBearerInfoWCDMA:
                p->bearerType = QNetworkConfiguration::BearerWCDMA;
                break;
            case EBearerInfoCDMA2000:
                p->bearerType = QNetworkConfiguration::BearerCDMA2000;
                break;
            case EBearerInfoGPRS:
                p->bearerType = QNetworkConfiguration::Bearer2G;
                break;
            case EBearerInfoHSCSD:
                p->bearerType = QNetworkConfiguration::Bearer2G;
                break;
            case EBearerInfoEdgeGPRS:
                p->bearerType = QNetworkConfiguration::Bearer2G;
                break;
            case EBearerInfoWcdmaCSD:
                p->bearerType = QNetworkConfiguration::BearerWCDMA;
                break;
            case EBearerInfoHSDPA:
                p->bearerType = QNetworkConfiguration::BearerHSPA;
                break;
            case EBearerInfoHSUPA:
                p->bearerType = QNetworkConfiguration::BearerHSPA;
                break;
            case EBearerInfoHSxPA:
                p->bearerType = QNetworkConfiguration::BearerHSPA;
                break;
            }
        }

        ++i;
    }
}
#endif

bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr,
                                               QNetworkConfiguration::StateFlags newState)
{
    ptr->mutex.lock();
    if (newState != ptr->state) {
        ptr->state = newState;
        ptr->mutex.unlock();

        mutex.unlock();
        emit configurationChanged(ptr);
        mutex.lock();

        return true;
    } else {
        ptr->mutex.unlock();
    }
    return false;
}

/* changeConfigurationStateAtMinTo function does not overwrite possible better
 * state (e.g. Discovered state does not overwrite Active state) but
 * makes sure that state is at minimum given state.
*/
bool SymbianEngine::changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr,
                                                    QNetworkConfiguration::StateFlags newState)
{
    ptr->mutex.lock();
    if ((newState | ptr->state) != ptr->state) {
        ptr->state = (ptr->state | newState);
        ptr->mutex.unlock();

        mutex.unlock();
        emit configurationChanged(ptr);
        mutex.lock();

        return true;
    } else {
        ptr->mutex.unlock();
    }
    return false;
}

/* changeConfigurationStateAtMaxTo function overwrites possible better
 * state (e.g. Discovered state overwrites Active state) and
 * makes sure that state is at maximum given state (e.g. Discovered state
 * does not overwrite Defined state).
*/
bool SymbianEngine::changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr,
                                                    QNetworkConfiguration::StateFlags newState)
{
    ptr->mutex.lock();
    if ((newState & ptr->state) != ptr->state) {
        ptr->state = (newState & ptr->state);
        ptr->mutex.unlock();

        mutex.unlock();
        emit configurationChanged(ptr);
        mutex.lock();

        return true;
    } else {
        ptr->mutex.unlock();
    }
    return false;
}

void SymbianEngine::startCommsDatabaseNotifications()
{
    if (!iWaitingCommsDatabaseNotifications) {
        iWaitingCommsDatabaseNotifications = ETrue;
        if (!IsActive()) {
            SetActive();
            // Start waiting for new notification
            ipCommsDB->RequestNotification(iStatus);
        }
    }
}

void SymbianEngine::stopCommsDatabaseNotifications()
{
    if (iWaitingCommsDatabaseNotifications) {
        iWaitingCommsDatabaseNotifications = EFalse;
        Cancel();
    }
}

void SymbianEngine::RunL()
{
    QMutexLocker locker(&mutex);

    if (iStatus != KErrCancel) {
        // By default, start relistening notifications. Stop only if interesting event occurred.
        iWaitingCommsDatabaseNotifications = true;
        RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int());
        switch (event) {
        case RDbNotifier::ECommit:   /** A transaction has been committed.  */
        case RDbNotifier::ERecover:  /** The database has been recovered    */
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
            qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
#endif
            // Mark that there is update pending. No need to ask more events,
            // as we know we will be updating anyway when the timer expires.
            if (!iUpdatePending) {
                iUpdatePending = true;
                iWaitingCommsDatabaseNotifications = false;
                // Update after random time, so that many processes won't
                // start updating simultaneously
                updateConfigurationsAfterRandomTime();
            }
            break;
        default:
            // Do nothing
            break;
        }
    }

    if (iWaitingCommsDatabaseNotifications) {
        if (!IsActive()) {
            SetActive();
            // Start waiting for new notification
            ipCommsDB->RequestNotification(iStatus);
        }
    }
}

void SymbianEngine::DoCancel()
{
    QMutexLocker locker(&mutex);

    ipCommsDB->CancelRequestNotification();
}

void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
{
    QMutexLocker locker(&mutex);

    switch (aEvent.EventType()) {
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
    case EConnMonBearerInfoChange:
        {
        CConnMonBearerInfoChange* realEvent;
        realEvent = (CConnMonBearerInfoChange*) &aEvent;
        TUint connectionId = realEvent->ConnectionId();
        if (connectionId == EBearerIdAll) {
            //Network level event
            TConnMonBearerInfo bearerInfo = (TConnMonBearerInfo)realEvent->BearerInfo();
            updateMobileBearerToConfigs(bearerInfo);
        }
        break;
        }
#endif
    case EConnMonConnectionStatusChange:
        {
        CConnMonConnectionStatusChange* realEvent;
        realEvent = (CConnMonConnectionStatusChange*) &aEvent;
        TInt connectionStatus = realEvent->ConnectionStatus();
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
        qDebug() << "QNCM Connection status : " << QString::number(connectionStatus) << " , connection monitor Id : " << realEvent->ConnectionId();
#endif
        if (connectionStatus == KConfigDaemonStartingRegistration) {
            TUint connectionId = realEvent->ConnectionId();
            TUint subConnectionCount = 0;
            TUint apId;            
            TRequestStatus status;
            iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
            User::WaitForRequest(status);

            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
            if (!ptr) {
                // Check if status was regarding EasyWLAN
                ptr = configurationFromEasyWlan(apId, connectionId);
            }
#endif
            if (ptr) {
                ptr->mutex.lock();
                toSymbianConfig(ptr)->connectionId = connectionId;
                ptr->mutex.unlock();
                QT_TRYCATCH_LEAVING(
                    emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
                                                   connectionId, QNetworkSession::Connecting)
                );
            }
        } else if (connectionStatus == KLinkLayerOpen) {
            // Connection has been successfully opened
            TUint connectionId = realEvent->ConnectionId();
            TUint subConnectionCount = 0;
            TUint apId;            
            TRequestStatus status;
            iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
            User::WaitForRequest(status);
            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
            if (!ptr) {
                // Check for EasyWLAN
                ptr = configurationFromEasyWlan(apId, connectionId);
            }
#endif
            if (ptr) {
                ptr->mutex.lock();
                toSymbianConfig(ptr)->connectionId = connectionId;
                ptr->mutex.unlock();

                // Configuration is Active
                QT_TRYCATCH_LEAVING(
                    if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) {
                        updateStatesToSnaps();
                    }
                    emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
                                                   connectionId, QNetworkSession::Connected);

                    if (!iOnline) {
                        iOnline = true;
                        emit this->onlineStateChanged(iOnline);
                    }
                );
            }
        } else if (connectionStatus == KConfigDaemonStartingDeregistration) {
            TUint connectionId = realEvent->ConnectionId();
            QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
            if (ptr) {
                QT_TRYCATCH_LEAVING(
                    emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
                                                   connectionId, QNetworkSession::Closing)
                );
            }
        } else if (connectionStatus == KLinkLayerClosed ||
                   connectionStatus == KConnectionClosed) {
            // Connection has been closed. Which of the above events is reported, depends on the Symbian
            // platform.
            TUint connectionId = realEvent->ConnectionId();
            QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
            if (ptr) {
                // Configuration is either Defined or Discovered
                QT_TRYCATCH_LEAVING(
                    if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
                        updateStatesToSnaps();
                    }
                    emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
                                                   connectionId, QNetworkSession::Disconnected);
                );
            }
            
            bool online = false;
            foreach (const QString &iface, accessPointConfigurations.keys()) {
                QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
                QMutexLocker configLocker(&ptr->mutex);
                if (ptr->state == QNetworkConfiguration::Active) {
                    online = true;
                    break;
                }
            }
            if (iOnline != online) {
                iOnline = online;
                QT_TRYCATCH_LEAVING(emit this->onlineStateChanged(iOnline));
            }
        }
        }
        break;    

    case EConnMonIapAvailabilityChange:
        {
        CConnMonIapAvailabilityChange* realEvent;
        realEvent = (CConnMonIapAvailabilityChange*) &aEvent;
        TConnMonIapInfo iaps = realEvent->IapAvailability();
        QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys();
        for ( TUint i = 0; i < iaps.Count(); i++ ) {
            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
                            QString::number(qHash(iaps.iIap[i].iIapId));

            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
            if (ptr) {
                // Configuration is either Discovered or Active 
                QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered));
                unDiscoveredConfigs.removeOne(ident);
            }
        }
        foreach (const QString &iface, unDiscoveredConfigs) {
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
            if (ptr) {
                // Configuration is Defined
                QT_TRYCATCH_LEAVING(changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined));
            }
        }
        // Something has in IAPs, update states to SNAPs
        updateStatesToSnaps();
        }
        break;

    case EConnMonCreateConnection:
        {
        // This event is caught to keep connection monitor IDs up-to-date.
        CConnMonCreateConnection* realEvent;
        realEvent = (CConnMonCreateConnection*) &aEvent;
        TUint subConnectionCount = 0;
        TUint apId;
        TUint connectionId = realEvent->ConnectionId();
        TRequestStatus status;
        iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
        User::WaitForRequest(status);
        QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
        QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
        if (!ptr) {
            // If IAP was not found, check if the update was about EasyWLAN
            ptr = configurationFromEasyWlan(apId, connectionId);
        }
#endif
        if (ptr) {
            QMutexLocker configLocker(&ptr->mutex);
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
            qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << toSymbianConfig(ptr)->connectionId << connectionId << ptr->name;
#endif
            toSymbianConfig(ptr)->connectionId = connectionId;
        }
        }
        break;
    default:
        // For unrecognized events
        break;
    }
}

/*
    Returns the network configuration that matches the given SSID.
*/
QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromSsid(const QString &ssid)
{
    QMutexLocker locker(&mutex);

    // Browser through all items and check their name for match
    QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator i =
        accessPointConfigurations.constBegin();
    while (i != accessPointConfigurations.constEnd()) {
        QNetworkConfigurationPrivatePointer ptr = i.value();

        QMutexLocker configLocker(&ptr->mutex);

        if (ptr->name == ssid) {
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
            qDebug() << "QNCM EasyWlan uses real SSID: " << ssid;
#endif
            return ptr;
        }
        ++i;
    }

    return QNetworkConfigurationPrivatePointer();
}

#ifdef SNAP_FUNCTIONALITY_AVAILABLE
// Tries to derive configuration from EasyWLAN.
// First checks if the interface brought up was EasyWLAN, then derives the real SSID,
// and looks up configuration based on that one.
QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId,
                                                                             TUint connectionId)
{
    if (apId == iCmManager.EasyWlanIdL()) {
        TRequestStatus status;
        TBuf<50> easyWlanNetworkName;
        iConnectionMonitor.GetStringAttribute( connectionId, 0, KNetworkName,
                                               easyWlanNetworkName, status );
        User::WaitForRequest(status);
        if (status.Int() == KErrNone) {
            const QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(),
                                                        easyWlanNetworkName.Length());

            // Browser through all items and check their name for match
            QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator i =
                accessPointConfigurations.constBegin();
            while (i != accessPointConfigurations.constEnd()) {
                QNetworkConfigurationPrivatePointer ptr = i.value();

                QMutexLocker configLocker(&ptr->mutex);

                if (ptr->name == realSSID) {
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
                    qDebug() << "QNCM EasyWlan uses real SSID: " << realSSID;
#endif
                    return ptr;
                }
                ++i;
            }
        }
    }
    return QNetworkConfigurationPrivatePointer();
}
#endif

// Sessions may use this function to report configuration state changes,
// because on some Symbian platforms (especially Symbian^3) all state changes are not
// reported by the RConnectionMonitor, in particular in relation to stop() call,
// whereas they _are_ reported on RConnection progress notifier used by sessions --> centralize
// this data here so that other sessions may benefit from it too (not all sessions necessarily have
// RConnection progress notifiers available but they relay on having e.g. disconnected information from
// manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome.
void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState)
{
    QMutexLocker locker(&mutex);

#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
    qDebug() << "QNCM A session reported state change for IAP ID: " << accessPointId << " whose new state is: " << newState;
#endif
    switch (newState) {
    case QNetworkSession::Disconnected:
        {
            QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX +
                            QString::number(qHash(accessPointId));
            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
            if (ptr) {
                // Configuration is either Defined or Discovered
                if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
                    updateStatesToSnaps();
                }

                locker.unlock();
                emit configurationStateChanged(toSymbianConfig(ptr)->numericIdentifier(),
                                               toSymbianConfig(ptr)->connectionIdentifier(),
                                               QNetworkSession::Disconnected);
                locker.relock();
            }
        }
        break;
    default:
        break;
    }
}

// Waits for 2..6 seconds.
void SymbianEngine::updateConfigurationsAfterRandomTime()
{
    int iTimeToWait = qMax(1000, (qAbs(qrand()) % 68) * 100);
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
    qDebug("QNCM waiting random time: %d ms", iTimeToWait);
#endif
    QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate()));
}

QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId)
{
    QNetworkConfiguration item;
    QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i =
            accessPointConfigurations.constBegin();
    while (i != accessPointConfigurations.constEnd()) {
        QNetworkConfigurationPrivatePointer ptr = i.value();
        if (toSymbianConfig(ptr)->connectionIdentifier() == aConnectionId)
            return ptr;

        ++i;
    }

    return QNetworkConfigurationPrivatePointer();
}

AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& owner,
                                                               RConnectionMonitor& connectionMonitor)
    : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor)
{
    CActiveScheduler::Add(this);  
}

AccessPointsAvailabilityScanner::~AccessPointsAvailabilityScanner()
{
    Cancel();
}

void AccessPointsAvailabilityScanner::DoCancel()
{
    iConnectionMonitor.CancelAsyncRequest(EConnMonGetPckgAttribute);
    iScanActive = EFalse;
    iOwner.iScanInQueue = EFalse;
}

void AccessPointsAvailabilityScanner::StartScanning()
{
    if (!iScanActive) {
        iScanActive = ETrue;
        if (iOwner.iFirstUpdate) {
            // On first update (the mgr is being instantiated) update only those bearers who
            // don't need time-consuming scans (WLAN).
            // Note: EBearerIdWCDMA covers also GPRS bearer
            iConnectionMonitor.GetPckgAttribute(EBearerIdWCDMA, 0, KIapAvailability, iIapBuf, iStatus);
        } else {
            iConnectionMonitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iIapBuf, iStatus);
        }

        if (!IsActive()) {
            SetActive();
        }
    } else {
        // Queue scan for getting WLAN info after first request returns
        if (iOwner.iFirstUpdate) {
            iOwner.iScanInQueue = ETrue;
        }
    }
}

void AccessPointsAvailabilityScanner::RunL()
{
    QMutexLocker locker(&iOwner.mutex);

    iScanActive = EFalse;
    if (iStatus.Int() != KErrNone) {
        iIapBuf().iCount = 0;
        QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(false,iIapBuf()));
    } else {
        QT_TRYCATCH_LEAVING(iOwner.accessPointScanningReady(true,iIapBuf()));
    }
}

QT_END_NAMESPACE

#endif // QT_NO_BEARERMANAGEMENT
