satengine/SatServer/Engine/src/CSatApnHandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:45:17 +0300
branchRCL_3
changeset 19 7d48bed6ce0c
parent 18 594d59766373
child 20 987c9837762f
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2002-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:  Handles APN operations
*
*/

// INCLUDE FILES
#include <cmmanager.h>
#include <cmmanagerext.h>
#include <cmconnectionmethod.h>
#include <cmconnectionmethodext.h>
#include <cmconnectionmethoddef.h>
#include <cmpluginpacketdatadef.h>
#include <cmdestination.h>
#include <cmmanagerdef.h>

#include    "MSatUtils.h"
#include    "CSatApnHandler.h"
#include    "SatLog.h"

const TUint32 KSatCMGranularity( 5 );

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

// -----------------------------------------------------------------------------
// CSatApnHandler::CSatApnHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CSatApnHandler::CSatApnHandler( MSatUtils& aUtils ) :
    iUtils( aUtils )
    {
    LOG( SIMPLE,
        "SATENGINE: CSatApnHandler::CSatApnHandler calling-exiting" )
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSatApnHandler* CSatApnHandler::NewL( MSatUtils& aUtils )
    {
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::NewL calling" )

    CSatApnHandler* self = new( ELeave )CSatApnHandler( aUtils );
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::NewL exiting" )
    return self;
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::Destructor
// -----------------------------------------------------------------------------
//
CSatApnHandler::~CSatApnHandler()
    {
    LOG( SIMPLE,
        "SATENGINE: CSatApnHandler::~CSatApnHandler calling" )
    LOG( SIMPLE,
        "SATENGINE: CSatApnHandler::~CSatApnHandler exiting" )
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::GetApnInfoL
// -----------------------------------------------------------------------------
//
void CSatApnHandler::GetApnInfoL(
    const RSat::TAccessName& aName,
    const RSat::TTextString& aUserLogin,
    const RSat::TTextString& aUserPwd,
    TUint32& aIapId,
    TUint32& aNwId,
    TBool& aApnCreated,
    const RPacketContext::TProtocolType& aPdpType,
    const TDesC8& aLocalAddress )
    {
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL calling" )


    // First check the length of the APN
    if ( !aName.Length() )
        {
        LOG( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL \
        aName.Length() == 0" )
        User::Leave( KErrNotFound );
        }

    // Format APN
    HBufC* formatName = FormatAPN( aName );

    if ( !formatName )
        {
        LOG( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL wrong APN name \
            format" )
        // APN was in false format, leave
        User::Leave( KErrArgument );
        }
    CleanupStack::PushL( formatName );

    // Reference params
    TUint32 iapId( 0 );
    TUint32 networkId( 0 );

    // Find if the connection method already exists 
    // Initialize the flags
    TBool found = EFalse;
    aApnCreated = EFalse;

    // Create CMManager Session
    RCmManager cmManager;
    cmManager.OpenLC();

    // Get the Connection Method list from the open CMManager session
    RArray<TUint32> array = RArray<TUint32>( KSatCMGranularity );
    CleanupClosePushL( array );

    cmManager.ConnectionMethodL( array );
    
    // Go through the Connection Method list to find if there is matched one
    HBufC* apnCM;

    LOG2( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL, \
                   required pdp type is %d", aPdpType )

    for( TInt i = 0; ( i < array.Count() ) && !found; ++i )
        {
        RCmConnectionMethod cm = cmManager.ConnectionMethodL( array[i] );
        
        CleanupClosePushL( cm );
        // query the APN of the Connection Method
        apnCM = cm.GetStringAttributeL( CMManager::EPacketDataAPName );
        CleanupStack::PushL( apnCM );
        // query the pdpType of the Connection Method
        TInt pdpType = cm.GetIntAttributeL( CMManager::EPacketDataPDPType );

        
        if ( ( pdpType == aPdpType ) && ( *apnCM == *formatName ) )
            {
            // Found the Connection Method, query the IapId and NwId
            LOG( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL, \
                          Record found" )

            // Get IAP Id, Network Id
            networkId = cm.GetIntAttributeL( CMManager::ECmNetworkId );
            LOG2( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL, \
                           networkId %d", networkId ) 
            
            iapId = cm.GetIntAttributeL( CMManager::ECmIapId );
            LOG2( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL, \
                           iapId %d", iapId )
    
            found = ETrue;
            }
        CleanupStack::PopAndDestroy( apnCM );
        CleanupStack::PopAndDestroy( &cm );    
        }        
 
    CleanupStack::PopAndDestroy( &array );

    if ( !found )
        {
        // No Connection Method found, insert a new one
    
        LOG( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL, \
                      Record Not found, insert a new one" )
        
        TRAPD( insertError, InsertRecordL( *formatName, aUserLogin, 
               aUserPwd, iapId, networkId, aPdpType, aLocalAddress ) )

        if ( KErrNone == insertError )
            {
            // Insert OK
            LOG( NORMAL, "SATENGINE: CSatApnHandler::GetApnInfoL, \
                          new record inserted" )
            aApnCreated = ETrue;
            }
        }
    
    CleanupStack::PopAndDestroy( &cmManager );
    CleanupStack::PopAndDestroy( formatName );

    // Set return values
    aIapId = iapId;
    aNwId = networkId;

    LOG( SIMPLE, "SATENGINE: CSatApnHandler::GetApnInfoL exiting" )
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::DeleteApnL
// -----------------------------------------------------------------------------
//
void CSatApnHandler::DeleteApnL( TUint32 aApnId )
    {
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::DeleteApnL calling" )

    if ( aApnId )
        { 
        // Create CMManager Session
        RCmManagerExt cmManager;
        cmManager.OpenLC();
        
        // Get the connection method
        RCmConnectionMethodExt cm;
        cm = cmManager.ConnectionMethodL( aApnId );
        CleanupClosePushL( cm );

        cm.DeleteL();
        LOG2( SIMPLE, "SATENGINE: CSatApnHandler::DeleteApnL, \
                       delete the connection method %d", aApnId )

        CleanupStack::PopAndDestroy( &cm );
        CleanupStack::PopAndDestroy( &cmManager );
        }

    LOG( SIMPLE, "SATENGINE: CSatApnHandler::DeleteApnL exiting" )
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::InsertRecordL
// -----------------------------------------------------------------------------
//
void CSatApnHandler::InsertRecordL(
    const TDesC& aReqApn,
    const RSat::TTextString& aUserLogin,
    const RSat::TTextString& aUserPwd,
    TUint32& aIapId,
    TUint32& aNwId,
    const RPacketContext::TProtocolType aPdpType,
    const TDesC8& aLocalAddress )
    {
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::InsertRecordL calling" )

    LOG2( NORMAL, "SATENGINE: CSatApnHandler::InsertRecordL, apn is %S", 
        &aReqApn )
    
    // Create CMManager Session
    RCmManagerExt cmManager;
    cmManager.OpenLC();

    // Create a connection method without destination. So when we can find 
    // the connection method by going through the connection method list.
    RCmConnectionMethodExt cm;
    cm = cmManager.CreateConnectionMethodL( KUidPacketDataBearerType );
    CleanupClosePushL( cm );
    
    // This is shown in GS in Access Point list
    cm.SetStringAttributeL( CMManager::ECmName, iUtils.BipApnName() );    
    // GPRS connection name
    cm.SetStringAttributeL( CMManager::EPacketDataAPName, aReqApn );   
    // IPv4 or IPv6
    cm.SetIntAttributeL( CMManager::EPacketDataPDPType, aPdpType );

    // Set the local IP address (if any)
    if ( aLocalAddress.Length() )
        {
        LOG2( SIMPLE, "SATENGINE: CSatApnHandler::InsertRecordL, Local addr \
            length: %i", aLocalAddress.Length() )
        cm.SetString8AttributeL( CMManager::EPacketDataPDPAddress, 
            aLocalAddress );
        }

    cm.SetBoolAttributeL( CMManager::ECmWapIPSecurity, EFalse );
    cm.SetIntAttributeL( CMManager::ECmWapIPWSPOption, 
                         CMManager::ECmWapWspOptionConnectionOriented );
    cm.SetBoolAttributeL( CMManager::EPacketDataDisablePlainTextAuth, EFalse );
    cm.SetBoolAttributeL( CMManager::ECmIFPromptForAuth, EFalse );

    if ( aUserLogin != KNullDesC )
        {
        LOG2( NORMAL, "SATENGINE: CSatApnHandler::InsertRecordL, \
            username is %S", &aUserLogin ) 
        cm.SetStringAttributeL( CMManager::ECmIFAuthName, aUserLogin );

        if ( aUserPwd != KNullDesC )
            {
            LOG2( NORMAL, "SATENGINE: CSatApnHandler::InsertRecordL, \
                pwd is %S", &aUserPwd ) 
            cm.SetStringAttributeL( CMManager::ECmIFAuthPass, aUserPwd );
            }
        }
    
    // Update the access point ID for use later.
    cm.UpdateL();

    // Get IAP Id, Network Id
    aNwId = cm.GetIntAttributeL( CMManager::ECmNetworkId );
    LOG2( SIMPLE, "SATENGINE: CSatApnHandler::InsertRecordL, \
                   Nwid is %d", aNwId ) 
    
    aIapId = cm.GetIntAttributeL( CMManager::ECmIapId );
    LOG2( SIMPLE, "SATENGINE: CSatApnHandler::InsertRecordL, \
                   aIpId is %d", aIapId )

    CleanupStack::PopAndDestroy( &cm );
    CleanupStack::PopAndDestroy( &cmManager );

    LOG( SIMPLE, "SATENGINE: CSatApnHandler::InsertRecordL exiting" )
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::FormatAPN
// -----------------------------------------------------------------------------
//
HBufC* CSatApnHandler::FormatAPN( const RSat::TAccessName& 
    aReqApn ) const
    {
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::FormatAPN calling" )

    // Length of the access point name
    const TInt accessNameLength( aReqApn.Length() );
    TInt index( 0 );

    // Format APN coming from SIM. Remove length infos and add dots
    // from the requested APN. The APN format is, for example,
    // '4Some9accesspnt2fi' and after the format the formatted APN
    // should be 'Some.accesspnt.fi'
    HBufC* formatApnName = HBufC::New( aReqApn.MaxLength() );

    if ( formatApnName )
        {
        TPtr formApn( formatApnName->Des() );

        // Indicates is the APN format correct. Can be detected only in loops.
        TBool correctFormat( ETrue );

        // Loop requested APN. The first byte is always the length
        for ( index = 0; index < accessNameLength && correctFormat; index++ )
            {
            // Next byte is the length of the next label
            const TInt length( aReqApn[index] );

            // Label length cannot be bigger than the length of the APN
            if ( ( index + length ) > accessNameLength )
                {
                LOG( SIMPLE, "SATENGINE: CSatApnHandler::FormatAPN \
                ( index + length ) > accessNameLength" )
                correctFormat = EFalse;
                }

            // Append the label
            for ( TInt j = 0; j < length && correctFormat; j++ )
                {
                index++; // move to next index
                TChar next = aReqApn[index];
                formApn.Append( next );
                }

            // Add dot to APN if not end of APN
            if ( accessNameLength > index + 1 )
                {
                LOG( SIMPLE, "SATENGINE: CSatApnHandler::FormatAPN \
                accessNameLength > index + 1" )
                formApn.Append( '.' );
                }
            }
        LOG2( SIMPLE, "SATENGINE: CSatApnHandler::FormatAPN index: %i", index )

        // Check did we read all characters
        if ( !correctFormat || ( index != accessNameLength ) )
            {
            // Format was not correct, return zero
            formApn.Zero();
            formApn.SetLength( 0 );
            }
        else
            {
            LOG( SIMPLE, "SATENGINE: CSatApnHandler::FormatAPN lower case" )
            // Put characters to lower case
            formApn.LowerCase();
            }

        LOG( SIMPLE, "SATENGINE: CSatApnHandler::FormatAPN exiting" )
        }

    return formatApnName;
    }

// -----------------------------------------------------------------------------
// CSatApnHandler::FindDefaultApL
// -----------------------------------------------------------------------------
//
TUint32 CSatApnHandler::FindDefaultApL(
        const RPacketContext::TProtocolType& aPdpType )
    {
    LOG( SIMPLE, "SATENGINE: CSatApnHandler::FindDefaultApL calling" );
    TUint32 defaultIap( 0 );
    TInt pdpType;
    TBool isFound( EFalse );

    // create a network destination
    RCmDestination des;
    RCmConnectionMethod cm;

    // Create CMManager Session
    RCmManager cmManager;
    cmManager.OpenL();
    CleanupClosePushL( cmManager );

    // Get the Connection Method list from the open CMManager session
    RArray<TUint32> array( KSatCMGranularity );
    CleanupClosePushL( array );

    // list all available destinations' id
    cmManager.AllDestinationsL( array );
    for( TInt i = 0; ( i < array.Count() ) && !isFound; ++i )
        {
        des = cmManager.DestinationL( array[i] );
        CleanupClosePushL( des );

        if ( CMManager::ESnapPurposeInternet ==
        des.MetadataL( CMManager::ESnapMetadataPurpose ) )
            {
            LOG( SIMPLE, "SATENGINE: CSatApnHandler::FindDefaultApL \
            the fixed destination is identified as 'Internet'" );
            for( TInt j = 0; ( j < des.ConnectionMethodCount() ) &&
            !isFound; ++j )
                {
                cm = des.ConnectionMethodL( j );
                CleanupClosePushL( cm );
                pdpType = cm.GetIntAttributeL(
                        CMManager::EPacketDataPDPType );
                LOG2( SIMPLE, "SATENGINE: CSatApnHandler::FindDefaultApL \
                        current protocol type is %d", pdpType )
                if ( pdpType == aPdpType )
                    {
                    defaultIap = cm.GetIntAttributeL( CMManager::ECmIapId );
                    isFound  = ETrue;
                    LOG2( SIMPLE, "SATENGINE: CSatApnHandler::FindDefaultApL \
                            default iap had been found %d", defaultIap )
                    }
                CleanupStack::PopAndDestroy( &cm );
                }
            }
        CleanupStack::PopAndDestroy( &des );
        }
    CleanupStack::PopAndDestroy( &array );
    CleanupStack::PopAndDestroy( &cmManager );

    if ( !isFound )
        {
        LOG( SIMPLE, "SATENGINE: CSatApnHandler: default AP not found" );
        User::Leave( KErrNotFound );
        }

    LOG( SIMPLE, "SATENGINE: CSatApnHandler::FindDefaultApL exit" )
    return defaultIap;
    }
//  End of File