commondrm/drmutility/src/drmutilityconnection.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:29:38 +0300
branchRCL_3
changeset 26 1221b68b8a5f
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description:  Connection manager for DRM
 *
 */

// INCLUDE FILES
#include <es_sock.h>
#include <cmconnectionmethod.h>
#include <cmdestination.h>
#include <cmconnectionmethoddef.h>
#include <cmmanager.h>
#include <extendedconnpref.h>
#include <cmapplicationsettingsui.h> // CCmApplicationSettingsUi
#include <es_enum.h>
#include <cdbcols.h> // IAP, COMMDB_ID
#include "drmutilityconnection.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "drmutilityconnectionTraces.h"
#endif

// ================= MEMBER FUNCTIONS =======================


// -----------------------------------------------------------------------------
// HasDefaultConnectionL
// Finds default IAP id
// @return Etrue: valid AP found
//         EFalse: valid AP not found
// @leave system wide error codes
// -----------------------------------------------------------------------------
//
TBool DRM::CDrmUtilityConnection::HasDefaultConnectionL()
    {
    TBool hasDefault(EFalse);
    TCmDefConnValue defConn;
    RCmManager cmManager;
    cmManager.OpenLC();
    cmManager.ReadDefConnL(defConn);
    if (defConn.iType == ECmDefConnConnectionMethod)
        {
        cmManager.GetConnectionMethodInfoIntL(defConn.iId,
                CMManager::ECmIapId);
        hasDefault = ETrue;
        }
    else if (defConn.iType == ECmDefConnDestination)
        {
        RCmDestination dest(cmManager.DestinationL(defConn.iId));
        CleanupClosePushL(dest);

        if (dest.ConnectionMethodCount() <= 0)
            {
            User::Leave(KErrNotFound);
            }

        RCmConnectionMethod cMeth(dest.ConnectionMethodL(0));
        CleanupClosePushL(cMeth);

        cMeth.GetIntAttributeL(CMManager::ECmIapId);
        CleanupStack::PopAndDestroy(&cMeth);
        CleanupStack::PopAndDestroy(&dest);
        hasDefault = ETrue;
        }
    CleanupStack::PopAndDestroy(&cmManager);
    return hasDefault;
    }

// -----------------------------------------------------------------------------
// CDrmUtilityConnection::HasAccessPointsL
// -----------------------------------------------------------------------------
//
TBool DRM::CDrmUtilityConnection::HasAccessPointsL()
    {
    TInt apCount(0);
    RCmManager cmManager;
    CleanupClosePushL(cmManager);
    cmManager.OpenL();
    RArray<TUint32> aps;
    CleanupClosePushL(aps);
    cmManager.ConnectionMethodL(aps, EFalse, EFalse, ETrue);
    apCount = aps.Count();
    CleanupStack::PopAndDestroy(2, &cmManager); //aps, cmManager
    return apCount > 0;
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::NewLC
// ---------------------------------------------------------------------------
//
DRM::CDrmUtilityConnection* DRM::CDrmUtilityConnection::NewLC(
        const TBool aAllowQueries)
    {
    CDrmUtilityConnection* conn = new (ELeave) CDrmUtilityConnection(
            aAllowQueries);
    CleanupStack::PushL(conn);
    conn->ConstructL();
    return conn;
    }
// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::NewL
// ---------------------------------------------------------------------------
//
DRM::CDrmUtilityConnection* DRM::CDrmUtilityConnection::NewL(
        const TBool aAllowQueries)
    {
    CDrmUtilityConnection* conn = CDrmUtilityConnection::NewLC(aAllowQueries);
    CleanupStack::Pop(conn);
    return conn;
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::~CDrmUtilityConnection
// ---------------------------------------------------------------------------
//
DRM::CDrmUtilityConnection::~CDrmUtilityConnection()
    {
    Cancel();
    iConnection.Close();
    iSocketServ.Close();
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::ConnectL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::ConnectL(TRequestStatus* aStatus)
    {
    TInt error(KErrGeneral);
    iStatus = KRequestPending;

    if (iState == EInit)
        {

        // Make this part atomic by pushing closes on the stack.
        error = iSocketServ.Connect();
        if (!error)
            {
            error = iConnection.Open(iSocketServ);
            }
        }

    if (iState == EConnected)
        {
        error=iConnection.Stop();
        //error=iConnection.Stop(RConnection::EStopAuthoritative); //just in case still does not work
        // if autoriative stop does not work then must do something following follow
        // TNifProgressBuf iJalla;
        // loop iConnection.ProgressNotification(iJalla,iStatus,KConnProgressDefault); SetActive
        // at RunL if (iJalla.iStage < KConnectionDown)
        // reactiveteWaitClose();
        //iConnection.ProgressNotification(iJalla,iStatus,(KConnectionDown); (should loop till state KConnectionDown seen)
        iConnection.Close();
        iState = EInit;
        error = KErrNone;
        error = iConnection.Open(iSocketServ);
        }

    iParentStatus = aStatus;
    *iParentStatus = KRequestPending;

    CompleteSelf(error);
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::HasMoreConnectionAttempts
// ---------------------------------------------------------------------------
//
TBool DRM::CDrmUtilityConnection::HasMoreConnectionAttempts()
    {
    TBool ret(EFalse);
    switch (iType)
        {
        case EUsingPurposeInternet:
            if (iAllowQueries)
                {
                ret = ETrue;
                }
            else
                {
                ret = EFalse;
                }
            break;
        case EUsingQuery:
        case EFail:
            ret = EFalse;
            break;
        default:
            ret = ETrue;
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::IsConnected
// ---------------------------------------------------------------------------
//
TBool DRM::CDrmUtilityConnection::IsConnected(TUint32& aIap)
    {
    TBool ret(EFalse);
    
    if (iState == EConnected)
        {
        aIap = iIapId;
        ret = ETrue;
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::Close
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::Close()
    {
    //LOGLIT( "CDrmUtilityConnection::Close" )

    Cancel();
    iConnection.Close();
    iSocketServ.Close();
    iState = EInit;
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection:CDrmUtilityConnection:
// ---------------------------------------------------------------------------
//
DRM::CDrmUtilityConnection::CDrmUtilityConnection(const TBool aAllowQueries) :
    CActive(CActive::EPriorityStandard), iState(EInit),
            iType(EAttachExisting), iAllowQueries(aAllowQueries)
    {
    CActiveScheduler::Add(this);
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::ConstructL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::ConstructL()
    {
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::DoCancel
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::DoCancel()
    {
    iConnection.Close();
    iSocketServ.Close();
    CompleteParent(KErrCancel);
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::RunL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::RunL()
    {
    TInt error(iStatus.Int());
    if (iState == EInit)
        {
        User::LeaveIfError(error); // Handle errors in RunError().
        if (iType == EAttachExisting)
            {
            AttachExistingConnectionL();
            }
        else
            {
            iState = EConnecting;
            error = KErrNotFound;
            CompleteSelf(error);
            }
        }
    else if (iState == EConnecting)
        {
        if (!error)
            {
            iState = EConnected;
            CompleteSelf(error);
            }
        else if (error != KErrNotFound)
            {
            User::LeaveIfError(error);
            }
        else
            {
            switch (iType)
                {
                case EAttachExisting:
                    iType = EUsingDefault;
                    ConnectUsingDefaultL();
                    break;
                case EUsingDefault:
                    iType = EUsingPurposeOperator;
                    ConnectUsingSnapPurposeL(CMManager::ESnapPurposeOperator);
                    break;
                case EUsingPurposeOperator:
                    iType = EUsingPurposeInternet;
                    ConnectUsingSnapPurposeL(CMManager::ESnapPurposeInternet);
                    break;
                case EUsingPurposeInternet:
                    iType = EUsingQuery;
                    if (iAllowQueries)
                        {
                        ConnectUsingQueryL();
                        break;
                        }
                case EUsingQuery:
                    iType = EFail;
                case EFail:
                default:
                    User::Leave(KErrCouldNotConnect);
                    break;
                }
            }
        }
    else if (iState == EConnected)
        {
        UpdateIapIdL();
        CompleteParent(iStatus.Int());
        }
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::RunError
// ---------------------------------------------------------------------------
//
TInt DRM::CDrmUtilityConnection::RunError(TInt aError)
    {
    //LOGLIT( "CDrmUtilityConnection::RunError" )

    iConnection.Close();
    iSocketServ.Close();

    CompleteParent(aError);
    iState = EInit;
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::AttachExistingConnectionL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::AttachExistingConnectionL()
    {
    TConnectionInfoBuf connInfo;
    TUint count(0);
    TInt error(KErrNotFound);
    iStatus = KRequestPending;

    User::LeaveIfError(iConnection.EnumerateConnections(count));
    if (count)
        {
        // Select AP with largest index. (Latest created)
        User::LeaveIfError(iConnection.GetConnectionInfo(count, connInfo));
        User::LeaveIfError(iConnection.Attach(connInfo,
                RConnection::EAttachTypeNormal));
        iState = EConnected;
        error = KErrNone;
        }
    else
        {
        iState = EConnecting;
        }
    CompleteSelf(error);
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::ConnectUsingDefaultL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::ConnectUsingDefaultL()
    {
    // Create overrides
    TConnPrefList prefList;
    TExtendedConnPref prefs;

    if (!iAllowQueries)
        {
        prefs.SetNoteBehaviour(TExtendedConnPref::ENoteBehaviourConnSilent);
        }
    else
        {
        prefs.SetNoteBehaviour(TExtendedConnPref::ENoteBehaviourConnDisableQueries);
        }
        
    //Fetch default connection
    TBool hasDefault(ETrue);
    TCmDefConnValue defConn;
    RCmManager cmManager;
    cmManager.OpenLC();
    cmManager.ReadDefConnL(defConn);
    if (defConn.iType == ECmDefConnConnectionMethod)
        {
        prefs.SetIapId(defConn.iId);
        }
    else if (defConn.iType == ECmDefConnDestination)
        {
        prefs.SetSnapId(defConn.iId);
        }
    else
        {
        hasDefault = EFalse;
        }
    // End of fetch default connection
    CleanupStack::PopAndDestroy(&cmManager);
    if (hasDefault)
        {
        prefList.AppendL(&prefs);

        // Start an Outgoing Connection with overrides
        iState = EConnecting;
        iConnection.Start(prefList, iStatus);
        SetActive();
        }
    else
        {
        // No default found --> next iteration needed
        CompleteSelf(KErrNotFound);
        }
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::ConnectUsingSnapOperatorL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::ConnectUsingSnapPurposeL(
        const TUint32 aPurpose)
    {
    // Create overrides
    TConnPrefList prefList;
    TExtendedConnPref prefs;
    prefs.SetSnapPurpose(static_cast<CMManager::TSnapPurpose> (aPurpose));
    if (aPurpose != CMManager::ESnapPurposeUnknown)
        {
        if (!iAllowQueries)
            {
            prefs.SetNoteBehaviour(
                    TExtendedConnPref::ENoteBehaviourConnSilent);
            }
        else
            {
            prefs.SetNoteBehaviour(
                    TExtendedConnPref::ENoteBehaviourConnDisableQueries);
            }
        }
    else
        {
        prefs.SetConnSelectionDialog(ETrue);
        prefs.SetNoteBehaviour(TExtendedConnPref::ENoteBehaviourDefault);
        prefs.SetForcedRoaming(EFalse);
        prefs.SetBearerSet(TExtendedConnPref::EExtendedConnBearerUnknown);
        }
    prefList.AppendL(&prefs);
    iState = EConnecting;

    // Start an Outgoing Connection with overrides
    iConnection.Start(prefList, iStatus);
    SetActive();
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::ConnectUsingQueryL
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::ConnectUsingQueryL()
    {
    // Create overrides
    TConnPrefList prefList;
    TExtendedConnPref prefs;

    CCmApplicationSettingsUi* ui(CCmApplicationSettingsUi::NewLC());
    TCmSettingSelection selectedConn;

    TBool selected(ui->RunApplicationSettingsL(selectedConn));
    CleanupStack::PopAndDestroy(ui);
    ui=NULL;
    if (selected)
        {
        if (selectedConn.iResult == CMManager::EConnectionMethod)
            {
            prefs.SetIapId(selectedConn.iId);
            }
        else if (selectedConn.iResult == CMManager::EDestination)
            {
            prefs.SetSnapId(selectedConn.iId);
            }
        else if (selectedConn.iResult != CMManager::EDefaultConnection)
            {
            selected=EFalse;
            }
        }
    if (selected)
        {
        if (selectedConn.iResult != CMManager::EDefaultConnection)
            {
            prefList.AppendL(&prefs);
            // For ensuring possibly stale connections get disconnected first;
            iConnection.Close();
            iConnection.Open(iSocketServ);
            
            iConnection.Start(prefList, iStatus);
            }
        else
            {
            iConnection.Start(iStatus);
            }
        SetActive();
        }
    else
        {
        CompleteSelf(KErrCancel);
        }
    }
// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::CompleteSelf
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::CompleteSelf(TInt aError)
    {
    TRequestStatus* status(&iStatus);
    User::RequestComplete(status, aError);
    SetActive();
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::CompleteParent
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::CompleteParent(TInt aError)
    {
    if (iParentStatus)
        {
        User::RequestComplete(iParentStatus, aError);
        iParentStatus = NULL;
        }
    }

// ---------------------------------------------------------------------------
// DRM::CDrmUtilityConnection::UpdateIapId
// ---------------------------------------------------------------------------
//
void DRM::CDrmUtilityConnection::UpdateIapIdL()
    {
    TBuf<16> query;

    query.Format(_L("%s\\%s"), IAP, COMMDB_ID);
    User::LeaveIfError(iConnection.GetIntSetting(query, iIapId));
    
    }