omadrm/drmengine/roap/src/RoapConnection.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:21:16 +0100
branchRCL_3
changeset 27 1481bf457703
parent 26 1221b68b8a5f
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2002-2009 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 ROAP
*
*/


// INCLUDE FILES
#include <cmconnectionmethod.h>
#include <cmdestination.h>
#include <cmconnectionmethoddef.h>
#include <cmmanager.h>
#include <centralrepository.h>
#include <commdbconnpref.h>
#include <cdblen.h>
#include <es_enum.h>
#ifdef __SERIES60_NATIVE_BROWSER
#include <browseruisdkcrkeys.h>
#endif
#include "RoapConnection.h"
#include "RoapDef.h"
#include "RoapLog.h"



#ifndef __SERIES60_NATIVE_BROWSER
    const TUid KCRUidBrowser   = {0x10008D39};
    const TUint32 KBrowserDefaultAccessPoint =  0x0000000E;
    const TUint32 KBrowserAccessPointSelectionMode = 0x0000001E;
    const TUint32 KBrowserNGDefaultSnapId = 0x00000053;
#endif


// ================= LOCAL FUNCTIONS =========================================
// ---------------------------------------------------------------------------
// IapIdOfDefaultSnapL
// for trapping purposes only
// ---------------------------------------------------------------------------
//
LOCAL_C TUint32 IapIdOfDefaultSnapL(
    RCmManager& aCmManager,
    const TUint32 aDefaultSnap )
    {
    RCmDestination dest( aCmManager.DestinationL( aDefaultSnap ) );
    CleanupClosePushL( dest );
    TUint32 iapIdOfDest( 0 );

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

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

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

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

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::NewL
// ---------------------------------------------------------------------------
//
Roap::CRoapConnection* Roap::CRoapConnection::NewL()
    {
    CRoapConnection* conn = new (ELeave) CRoapConnection();
    CleanupStack::PushL( conn );
    conn->ConstructL();
    CleanupStack::Pop( conn );
    return conn;
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::~CRoapConnection
// ---------------------------------------------------------------------------
//
Roap::CRoapConnection::~CRoapConnection()
    {
    Cancel();
    iConnection.Close();
    iSocketServ.Close();
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::ConnectL
// ---------------------------------------------------------------------------
//
void Roap::CRoapConnection::ConnectL
( TUint32 aIap, TRequestStatus* aStatus )
    {
    LOGLIT( "CRoapConnection::ConnectL" )
    const TInt KAlwaysAskSelectionMode( 1 );
    const TInt KDestinationSelectionMode( 2 );

    if ( iState == EInit )
        {
        // Not connected. Attach to existing connection, or create new one if
        // allowed.
        iStatus = KErrRoapGeneral;

        // Make this part atomic by pushing closes on the stack.
        User::LeaveIfError( iSocketServ.Connect() );
        CleanupClosePushL<RSocketServ>( iSocketServ );
        User::LeaveIfError( iConnection.Open( iSocketServ ) );
        CleanupClosePushL<RConnection>( iConnection );

        TConnectionInfoBuf connInfo;
        TInt ap = 0;
        TInt alwaysAsk = 0;
        TUint count;
        User::LeaveIfError( iConnection.EnumerateConnections( count ) );
        TUint i;
        if ( count )
            {
            // Select from existing connections. Try to make AP match.
            for ( i = count; i; i-- )
                {
                // Note: GetConnectionInfo expects 1-based index.
                User::LeaveIfError( iConnection.GetConnectionInfo( i, connInfo ) );
                if ( aIap == 0 || connInfo().iIapId == aIap )
                    {
                    // "Accept any" or AP match. Attach to this one.
                    break;
                    }
                }
            if ( !i )
                {
                // No AP match, select AP with largest index.
                User::LeaveIfError
                    ( iConnection.GetConnectionInfo( count, connInfo ) );
                }
            User::LeaveIfError
                ( iConnection.Attach( connInfo, RConnection::EAttachTypeNormal ) );
            iState = EConnected;
            iStatus = KErrNone;
            }
        else
            {
            // No existing connections, create new one.
#ifdef __WINS__
            // WINS connection creation does not work if preferences are given.
            // Defaults are to be used always.
            iConnection.Start( iStatus );
#else
            // Note: the TCommDbConnPref must NOT be stack variable.
            // It must persist until completion of RConnection::Start().
            iConnPref.SetDirection( ECommDbConnectionDirectionOutgoing );
            //iConnPref.SetDialogPreference( ECommDbDialogPrefWarn )
            iConnPref.SetBearerSet( ECommDbBearerCSD | ECommDbBearerWcdma );
            // New connection is always created with user-selected AP
            // so 0 is used instead of aIap.

            TInt defaultSnap( 0 );
            CRepository* repository( NULL );
            repository = CRepository::NewL( KCRUidBrowser );
            CleanupStack::PushL( repository );

            repository->Get( KBrowserDefaultAccessPoint, ap);
            repository->Get( KBrowserAccessPointSelectionMode, alwaysAsk );
            repository->Get( KBrowserNGDefaultSnapId, defaultSnap );
            CleanupStack::PopAndDestroy( repository );
            repository = NULL;

            TUint32 iapd32 = 0;
            TInt err = KErrNone;

            if ( ap <= KErrNotFound && defaultSnap <= KErrNotFound )
                {
                alwaysAsk = KAlwaysAskSelectionMode;
                }
            else
                {
                RCmManager cmManager;
                cmManager.OpenLC();
                if ( !alwaysAsk )
                    {
                    TRAP( err, iapd32 = cmManager.GetConnectionMethodInfoIntL(
                            ap, CMManager::ECmIapId ) );
                    }
                else if ( alwaysAsk == KDestinationSelectionMode )
                    {
                    TRAP( err, iapd32 = IapIdOfDefaultSnapL(
                            cmManager, defaultSnap ) );
                    }
                CleanupStack::PopAndDestroy( &cmManager );
                }

            if ( err || alwaysAsk == KAlwaysAskSelectionMode )
                {
                // Always ask
                LOGLIT( "SetDialogPreference( ECommDbDialogPrefPrompt )" )
                iConnPref.SetDialogPreference( ECommDbDialogPrefPrompt );
                iapd32 = 0;
                }
            else
                {
                // User defined
                LOGLIT( "SetDialogPreference( ECommDbDialogPrefDoNotPrompt )" )
                iConnPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
                }

            iConnPref.SetIapId( iapd32 );
            iConnection.Start( iConnPref, iStatus );
#endif
            iState = EConnecting;
            SetActive();    // The only path with a real async request.
            }
        CleanupStack::Pop( 2, &iSocketServ ); // closing iConn and iSockServ
        // End of atomic part.
        }
    else
        {
        // Not expecting this to be called in other states.
        }

    iParentStatus = aStatus;
    *iParentStatus = KRequestPending;

    if ( !IsActive() )
        {
        // Unless we have an outstanding connect request (iConn.Start),
        // we are done.
        User::RequestComplete( iParentStatus, iStatus.Int() );
        iParentStatus = NULL;
        }
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::Close
// ---------------------------------------------------------------------------
//
void Roap::CRoapConnection::Close()
    {
    LOGLIT( "CRoapConnection::Close" )

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

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::IsConnected
// ---------------------------------------------------------------------------
//
TBool Roap::CRoapConnection::IsConnected( TUint32& aIap )
    {
    LOGLIT( "CRoapConnection::IsConnected" )

    TBool connected( EFalse );
    if( iState == EConnected )
        {
        TBuf<KCommsDbSvrMaxColumnNameLength * 2 + 1> iapId;
        _LIT( KFormatIapId, "%S\\%S" );
        TPtrC iap( IAP );
        TPtrC id( COMMDB_ID );
        iapId.Format( KFormatIapId, &iap, &id );
        TInt err = iConnection.GetIntSetting( iapId, aIap );
        connected = err ? EFalse : ETrue;
        }
    return connected;
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::CRoapConnection
// ---------------------------------------------------------------------------
//
Roap::CRoapConnection::CRoapConnection()
: CActive( CActive::EPriorityStandard ),
  iState( EInit )
    {
    CActiveScheduler::Add( this );
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::ConstructL
// ---------------------------------------------------------------------------
//
void Roap::CRoapConnection::ConstructL()
    {
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::DoCancel
// ---------------------------------------------------------------------------
//
void Roap::CRoapConnection::DoCancel()
    {
    LOGLIT( "CRoapConnection::DoCancel" )

    iConnection.Close();
    iSocketServ.Close();
    User::RequestComplete( iParentStatus, KErrCancel );
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::RunL
// ---------------------------------------------------------------------------
//
void Roap::CRoapConnection::RunL()
    {
    LOGLIT( "CCRoapConnection::RunL" )

    User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().

    iState = EConnected;
    User::RequestComplete( iParentStatus, iStatus.Int() );
    iParentStatus = NULL;
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::RunError
// ---------------------------------------------------------------------------
//
TInt Roap::CRoapConnection::RunError( TInt  /* aError */ )
    {
    LOGLIT( "CRoapConnection::RunError" )

    iConnection.Close();
    iSocketServ.Close();
    iState = EInit;
    User::RequestComplete( iParentStatus, iStatus.Int() );
    iParentStatus = NULL;
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::SocketServ
// ---------------------------------------------------------------------------
//
RSocketServ& Roap::CRoapConnection::SocketServ()
    {
    return iSocketServ;
    }

// ---------------------------------------------------------------------------
// Roap::CRoapConnection::Conn
// ---------------------------------------------------------------------------
//
RConnection& Roap::CRoapConnection::Conn()
    {
    return iConnection;
    }