alwayson_net_plugin/pdpcontextmanager2/src/caoconnectionimplstub.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 11 May 2010 16:35:05 +0300
branchRCL_3
changeset 16 c45d4fe2ff0a
parent 0 5a93021fdf25
permissions -rw-r--r--
Revision: 201017 Kit: 201019

/*
* Copyright (c) 2004,2006 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:  Implements the CAOConnectionImpl class
*
*/


// INCLUDE FILES
#include <es_enum.h>
#include <ETELPCKT.H>
#include <in_sock.h>

#include "caoconnectionimplstub.h"
#include "logger.h"
#include "maoconnectionobserver.h"
#include "pdpcontextmanagerinternalpskeys.h"
#include "caoasyncwrapper.h"

// UNNAMED NAMESPACE FOR LOCAL DEFINITIONS
namespace
    {
    // CONSTANTS
    _LIT( KPanicCat, "ConnImplStub" );
    const TInt KDelay = 2000000; // 2 seconds
    
    // DATA TYPES
    enum TPanicReason
        {
        EAlreadyConnected,
        ENotActive,
        EInvalidState
        };
    
    // LOCAL FUNCTIONS
    LOCAL_C void Panic( TPanicReason aReason )
        {
        User::Panic( KPanicCat, aReason );
        }
    }

// METHODS

// ---------------------------------------------------------------------------
// Two-phased constructor.
// ---------------------------------------------------------------------------
//
CAOConnectionImpl* CAOConnectionImpl::NewL(
    MAOConnectionObserver& aObserver,
    MAOSettings&           aSettings,
    RSocketServ*           aSocketServ  )
    {
    LOG_1( _L("CAOConnectionImpl::NewL") );
    
    CAOConnectionImpl* self = new( ELeave ) CAOConnectionImpl(
        aObserver,
        aSettings,
        aSocketServ );
    
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self ); // self
    
    return self;
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CAOConnectionImpl::~CAOConnectionImpl()
    {
    LOG_1( _L("CAOConnectionImpl::~CAOConnectionImpl") );
    
    Cancel();
    delete iConnectionTimer;
    
    delete iPDPContextActivationSubscriber;
    iPDPContextActivationProperty.Delete(
        KConnectionCat,
        KPDPContextActivation );
    iPDPContextActivationProperty.Close();
    
    delete iPDPContextDisconnectionSubscriber;
    iPDPContextDisconnectionProperty.Delete(
        KConnectionCat,
        KPDPContextDisconnection );
    iPDPContextDisconnectionProperty.Close();
    }


// ---------------------------------------------------------------------------
// CAOConnectionImpl::ActivateConnection
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::ActivateConnection()
    {
    LOG_1( _L("CAOConnectionImpl::ActivateConnection") );
    
    __ASSERT_DEBUG( !IsActive() && iState == EDisconnected,
        Panic( EAlreadyConnected ) );

    // Change state -> EOpeningLink
    ChangeState( EOpeningLink );
    
    // Activate connection
    DoActivateConnection();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::AttachToExistingConnection
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::AttachToExistingConnection( TUint /*aConnectionId*/ )
    {
    LOG_1( _L("CAOConnectionImpl::AttachToExistingConnection") );
         
    __ASSERT_DEBUG( !IsActive() && iState == EDisconnected,
        Panic( EAlreadyConnected ) );
        
    // Change state -> EAttachingExistingConnection
    ChangeState( EAttachingExistingConnection );
    
    // Activate connection
    DoActivateConnection();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::CancelConnection
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::CancelConnection()
    {
    LOG_1( _L("CAOConnectionImpl::CancelConnection") );
    
    Cancel();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::IsConnectedToDefaultIAP
// ---------------------------------------------------------------------------
//
TBool CAOConnectionImpl::IsConnectedToDefaultIAP()
    {
    LOG_1( _L("CAOConnectionImpl::IsConnectedToDefaultIAP") );
    
    return iState != EDisconnected;
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::NumberOfConnections
// ---------------------------------------------------------------------------
//
TInt CAOConnectionImpl::NumberOfConnections()
    {
    LOG_1( _L("CAOConnectionImpl::NumberOfConnections") );
    
    return 0;
    }

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CAOConnectionImpl::CAOConnectionImpl(
    MAOConnectionObserver& aObserver,
    MAOSettings&           aSettings,
    RSocketServ*           aSocketServ  ):
    CActive( CActive::EPriorityStandard ),
    iObserver( aObserver ),
    iSettings( aSettings ),
    iSocketServ( aSocketServ )
    {
    LOG_1( _L("CAOConnectionImpl::CAOConnectionImpl") );
    
    CActiveScheduler::Add( this );
    }

// ---------------------------------------------------------------------------
// Symbian 2nd phase constructor
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::ConstructL()
    {
    LOG_1( _L("CAOConnectionImpl::ConstructL") );
    
    iConnectionTimer = CPeriodic::NewL( CActive::EPriorityStandard );
    
    // Define PDP context activation property
    User::LeaveIfError( iPDPContextActivationProperty.Define(
        KConnectionCat,
        KPDPContextActivation,
        RProperty::EInt ) );
    User::LeaveIfError( iPDPContextActivationProperty.Attach(
        KConnectionCat,
        KPDPContextActivation ) );
    iPDPContextActivationSubscriber =
        CAOAsyncWrapper<CAOConnectionImpl>::NewL(
            this,
            PDPContextActivationIssueRequest,
            PDPContextActivationRunL,
            PDPContextActivationDoCancel,
            NULL );
    SubscribePDPContextActivation();

    // Define PDP context activation property
    User::LeaveIfError( iPDPContextDisconnectionProperty.Define(
        KConnectionCat,
        KPDPContextDisconnection,
        RProperty::EInt ) );
    User::LeaveIfError( iPDPContextDisconnectionProperty.Attach(
        KConnectionCat,
        KPDPContextDisconnection ) );
    iPDPContextDisconnectionSubscriber =
        CAOAsyncWrapper<CAOConnectionImpl>::NewL(
            this,
            PDPContextDisconnectionIssueRequest,
            PDPContextDisconnectionRunL,
            PDPContextDisconnectionDoCancel,
            NULL );
    SubscribePDPContextDisconnection();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::ChangeState
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::ChangeState( TInternalState aNewState )
    {
    TInternalState old = iState;
    iState = aNewState;
    LOG_3( _L("CAOConnectionImpl::ChangeState >> Changing state %d -> %d"),
        old, iState );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::CompleteSelf
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::CompleteSelf( TRequestStatus& aStatus, TInt aReason )
    {
    LOG_2( _L("CAOConnectionImpl::CompleteSelf: aReason: %d"), aReason );
    
    __ASSERT_DEBUG( IsActive(), Panic( ENotActive ) );
    
    aStatus = KRequestPending;
    TRequestStatus* status = &aStatus;
    User::RequestComplete( status, aReason );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::ConnectionCallBack
// ---------------------------------------------------------------------------
//
TInt CAOConnectionImpl::ConnectionCallBack( TAny* aSelf )
    {
    LOG_1( _L("CAOConnectionImpl::ConnectionCallBack") );
    
    CAOConnectionImpl* self = static_cast<CAOConnectionImpl*>( aSelf );
    TRAPD( err, self->HandleConnectionCallBackL() );
    
    return err;
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::HandleConnectionCallBackL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::HandleConnectionCallBackL()
    {
    LOG_1( _L("CAOConnectionImpl::HandleConnectionCallBackL") );
    
    iConnectionTimer->Cancel();
    CompleteSelf( iStatus, iActivationError );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::DoActivateConnection
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::DoActivateConnection()
    {
    LOG_1( _L("CAOConnectionImpl::DoActivateConnection") );
    
    TCallBack cb( ConnectionCallBack, this );
    iConnectionTimer->Start( KDelay, KDelay, cb );
    iStatus = KRequestPending;
    SetActive();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::HandleOpeningLinkL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::HandleOpeningLinkL( TInt aStatus )
    {
    LOG_2( _L("CAOConnectionImpl::HandleOpeningLinkL: aStatus: %d"),
            aStatus );
    
    if ( aStatus == KErrNone )
        {
        // Everything ok - Link opened
        BroadcastPDPContextActivatedL();
        }
    else
        {
        // Report error
        BroadcastPDPContextActivationFailureL( aStatus );
        }
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::FailureReason
// ---------------------------------------------------------------------------
//
MAOConnectionManager::TFailureReason CAOConnectionImpl::FailureReason(
    TInt aError )
    {
    LOG_2( _L("CAOConnectionImpl::FailureReason: aError: %d"), aError );
    
    // Determine error cause
    MAOConnectionManager::TFailureReason reason =
        MAOConnectionManager::EPermanent;
    switch ( aError )
        {
        // Temporary cause
        case KErrGprsUserAuthenticationFailure:
        case KErrGprsActivationRejectedByGGSN:
        case KErrGprsActivationRejected:
        case KErrGprsServiceOptionTemporarilyOutOfOrder:
            {
            reason = MAOConnectionManager::ETemporary;
            break;
            }
        // Permanent cause
        default:
            {
            reason = MAOConnectionManager::EPermanent;
            break;
            }
        }
        
    LOG_2( _L("CAOConnectionImpl::FailureReason: Reason: %d"), reason );
            
    return reason;
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::HandleListeningAccessPointL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::HandleListeningAccessPointL( TInt aStatus )
    {
    LOG_2( _L("CAOConnectionImpl::HandleListeningAccessPointL: aStatus: %d"),
        aStatus );
    
    if ( aStatus == KErrNone )
        {
        // Everything ok - Continue listening
        iStatus = KRequestPending;
        SetActive();
        }
    else
        {
        // Report error
        BroadcastPDPContextDisconnectionL( aStatus );
        }
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::BroadcastPDPContextActivationFailureL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::BroadcastPDPContextActivationFailureL( TInt aError )
    {
    LOG_2( _L("CAOConnectionImpl::BroadcastPDPContextActivationFailureL: \
        aError: %d"), aError );
    
    ChangeState( EDisconnected );
    iObserver.HandlePDPContextActivationFailedL(
        FailureReason( aError ) );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::BroadcastPDPContextActivationFailureL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::BroadcastPDPContextDisconnectionL( TInt aError )
    {
    LOG_2( _L("CAOConnectionImpl::BroadcastPDPContextDisconnectionL: \
        aError: %d"), aError );
        
    ChangeState( EDisconnected );
    iObserver.HandlePDPContextDisconnectedL(
        MAOConnectionManager::ETemporary );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::HandleAttachingExistingConnectionL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::HandleAttachingExistingConnectionL( TInt aStatus )
    {
    LOG_2( _L("CAOConnectionImpl::HandleAttachingExistingConnectionL:\
        aStatus: %d"), aStatus );
    
    if ( aStatus == KErrNone )
        {
        // Broadcast PDP context activated
        BroadcastPDPContextActivatedL();
        }
    else
        {
        // Report error
        BroadcastPDPContextActivationFailureL( aStatus );
        }
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::SubscribePDPContextActivation
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::SubscribePDPContextActivation()
    {
    LOG_1( _L("CAOConnectionImpl::SubscribePDPContextActivation") );

    iPDPContextActivationSubscriber->IssueRequest();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::PDPContextActivationIssueRequest
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::PDPContextActivationIssueRequest(
    TRequestStatus& aStatus )
    {
    LOG_1( _L("CAOConnectionImpl::PDPContextActivationIssueRequest") );
    
    iPDPContextActivationProperty.Subscribe( aStatus );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::PDPContextActivationRunL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::PDPContextActivationRunL( TInt aStatus )
    {
    LOG_1( _L("CAOConnectionImpl::PDPContextActivationIssueRequest") );
    
    if ( aStatus == KErrNone )
        {
        TInt value = 0;
        TInt err = iPDPContextActivationProperty.Get( value );
        if ( err == KErrNone )
            {
            iActivationError = value;
            if ( IsActive() &&
                ( iState == EOpeningLink || 
                  iState == EAttachingExistingConnection ) )
                {
                CompleteSelf( iStatus, iActivationError );
                }
            }
        }
    SubscribePDPContextActivation();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::PDPContextActivationDoCancel
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::PDPContextActivationDoCancel()
    {
    LOG_1( _L("CAOConnectionImpl::PDPContextActivationDoCancel") );
    
    iPDPContextActivationProperty.Cancel();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::SubscribePDPContextDisconnection
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::SubscribePDPContextDisconnection()
    {
    LOG_1( _L("CAOConnectionImpl::SubscribePDPContextDisconnection") );
    
    iPDPContextDisconnectionSubscriber->IssueRequest();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::PDPContextDisconnectionIssueRequest
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::PDPContextDisconnectionIssueRequest(
    TRequestStatus& aStatus )
    {
    LOG_1( _L("CAOConnectionImpl::PDPContextDisconnectionIssueRequest") );
    
    iPDPContextDisconnectionProperty.Subscribe( aStatus );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::PDPContextDisconnectionRunL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::PDPContextDisconnectionRunL( TInt aStatus )
    {
    LOG_2( _L("CAOConnectionImpl::PDPContextDisconnectionRunL: aStatus: %d"),
        aStatus );
    
    if ( aStatus == KErrNone )
        {
        TInt value = 0;
        TInt err = iPDPContextDisconnectionProperty.Get( value );
        if ( err == KErrNone )
            {
            iDisconnectionError = value;
            if ( IsActive() && iState == EListeningAccessPoint )
                {
                CompleteSelf( iStatus, iDisconnectionError );
                }
            }
        }
    SubscribePDPContextDisconnection();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::PDPContextDisconnectionDoCancel
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::PDPContextDisconnectionDoCancel()
    {
    LOG_1( _L("CAOConnectionImpl::PDPContextDisconnectionIssueRequest") );
    
    iPDPContextDisconnectionProperty.Cancel();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::BroadcastPDPContextActivatedL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::BroadcastPDPContextActivatedL()
    {
    LOG_1( _L("CAOConnectionImpl::BroadcastPDPContextActivatedL") );
    
    ChangeState( EListeningAccessPoint );
    iStatus = KRequestPending;
    SetActive();
    iObserver.HandlePDPContextActivatedL();
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::RunL
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::RunL()
    {
    LOG_2( _L("CAOConnectionImpl::RunL: iStatus: %d"), iStatus.Int() );

    TInt status = iStatus.Int();
    switch ( iState )
        {
        case EDisconnected:
            {
            // Nothing to do
            break;
            }
        case EOpeningLink:
            {
            HandleOpeningLinkL( status );
            break;
            }
        case EListeningAccessPoint:
            {
            HandleListeningAccessPointL( status );
            break;
            }
        case EAttachingExistingConnection:
            {
            HandleAttachingExistingConnectionL( status );
            break;
            }
        default:
            {
            // Should not be here
            Panic( EInvalidState );
            break;
            }
        }
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::DoCancel
// ---------------------------------------------------------------------------
//
void CAOConnectionImpl::DoCancel()
    {
    LOG_1( _L("CAOConnectionImpl::DoCancel") );
    
    ChangeState( EDisconnected );
    CompleteSelf( iStatus, KErrCancel );
    }

// ---------------------------------------------------------------------------
// CAOConnectionImpl::RunError
// ---------------------------------------------------------------------------
//
TInt CAOConnectionImpl::RunError( TInt aError )
    {
    LOG_1( _L("CAOConnectionImpl::RunError") );
    
    return aError;
    }