dvrengine/CommonRecordingEngine/src/CCRConnection.cpp
changeset 0 822a42b6c3f1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dvrengine/CommonRecordingEngine/src/CCRConnection.cpp	Thu Dec 17 09:14:38 2009 +0200
@@ -0,0 +1,586 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:    Wrap rconnection*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "CCRConnection.h"
+#include <e32msgqueue.h>
+#include <ipvideo/CRTypeDefs.h>
+#include "videoserviceutilsLogger.h"
+
+// CONSTANTS
+// None.
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCRConnection::CCRConnection
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CCRConnection::CCRConnection( RSocketServ& aSockServer )
+  : CActive( EPriorityStandard ), 
+    iSockServer( aSockServer ),
+    iState( CCRConnection::EIdle )
+    {
+    // None
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCRConnection* CCRConnection::NewL( RSocketServ& aSockServer )
+    {
+    CCRConnection* self = new( ELeave ) CCRConnection( aSockServer );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::ConstructL()
+    {
+    CActiveScheduler::Add( this );
+    User::LeaveIfError( iConnection.Open( iSockServer ) );
+    User::LeaveIfError( iConMon.ConnectL() );
+
+    // Request bearer changes events from RConnectionMonitor
+    User::LeaveIfError( iConMon.NotifyEventL( *this ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::~CCRConnection
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CCRConnection::~CCRConnection()
+    {
+    LOG( "CCRConnection::~CCRConnection()" );
+
+    if ( iConMonProgressNotifyPending && iConnection.SubSessionHandle() )
+        {
+        LOG( "~CCRConnection CancelProgressNotification" );
+        iConnection.CancelProgressNotification();
+        }
+    
+    Cancel();
+    iConMon.CancelNotifications();
+    iConMon.Close();
+    CloseRConnection();
+    iObservers.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::Start
+// -----------------------------------------------------------------------------
+//      
+void CCRConnection::Attach( TUint aConnectionId ) 
+    {
+    LOG1( "CCRConnection::Attach: aConnectionId: %u", aConnectionId );
+    Cancel();
+    iCurrentConnectionId = aConnectionId;
+    iConMon.GetConnectionCount( iConnectionCount, iStatus );
+    SetActive();
+    iState = CCRConnection::EFindingAP;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::DoCancel
+// If we need to cancel.
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::DoCancel()
+    {
+    LOG( "CCRConnection::DoCancel" );
+    
+    if ( iState == CCRConnection::EFindingAP )
+        {
+        LOG( "CCRConnection::DoCancel in EFindingAP" );
+        iConMon.CancelAsyncRequest( EConnMonGetConnectionCount );
+        }
+    else if ( iState == CCRConnection::EFindingBearer )
+        {
+        LOG( "CCRConnection::DoCancel in EFindingBearer" ); 
+        iConMon.CancelAsyncRequest( EConnMonGetIntAttribute );
+        }
+    else if ( iState == CCRConnection::EOpen && iConnection.SubSessionHandle() )
+        {
+        LOG( "CCRConnection::DoCancel in EOpen" );
+        iConMonProgressNotifyPending = EFalse;
+        iConnection.CancelProgressNotification();
+        }
+    else if ( iState == CCRConnection::EConnecting )
+        {
+        LOG( "CCRConnection::DoCancel in EConnecting" );
+        // How to cancel a RConnection::Start?
+        }
+    
+    LOG( "CCRConnection::DoCancel() out" );
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::RunL
+// Request succesful completion.
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::RunL()
+    {
+    LOG2( "CCRConnection::RunL(), iState: %d, iStatus: %d", 
+        ( TInt )iState, iStatus.Int() );
+    
+    // Not pending any longer
+    iConMonProgressNotifyPending = EFalse;
+    
+    // Handle state
+    TInt err( KErrNone );   
+    if ( iStatus.Int() == KErrNone )
+        {
+        if (  iState == CCRConnection::EFindingAP )
+            {
+            err = FindApL();
+            }
+    	else if ( iState == CCRConnection::EFindingBearer )
+            {
+            FindBearerL();
+            }
+        else if ( iState == CCRConnection::EOpen )
+            {
+            NotificationL();
+            }
+        }
+    else
+        {
+        SendConnectionErrorToQueue( iStatus.Int() );
+        }
+
+    // Verify status
+    if ( err )
+        {
+        LOG1( "CCRConnection::RunL(), err: %d", err );  
+        SendConnectionErrorToQueue( err );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::SendConnectionErrorToQueue
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::SendConnectionErrorToQueue( TInt aError )
+    {
+    LOG1( "CCRConnection::SendConnectionErrorToQueue() aError: %d", aError );
+    
+    iState = CCRConnection::EIdle;
+    iCurrentConnectionId = 0;
+    iBearerType = EBearerUnknown;
+	CloseRConnection();
+    MCRConnectionObserver::TCRConnectionStatus status;
+    status = MCRConnectionObserver::ECRConnectionError;
+    
+    for ( TInt i( 0 ); i < iObservers.Count(); i++ )
+        {
+        iObservers[i]->ConnectionStatusChange( 0, status, aError );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::RunError
+// If anything goes wrong.
+// -----------------------------------------------------------------------------
+//
+TInt CCRConnection::RunError( TInt aError )
+    {
+    LOG1( "CCRConnection::RunError: aError %d", aError );
+    ( void )aError; // Prevent compiler warning
+    iState = CCRConnection::EIdle;
+    iCurrentConnectionId = 0;
+    iBearerType = EBearerUnknown;
+    CloseRConnection();
+    return KErrNone; 
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::CloseRConnection
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::CloseRConnection()
+    {
+    LOG( "CCRConnection::CloseRConnection()" );
+
+    if ( iConnection.SubSessionHandle() )
+    	{
+    	iConnection.Close();
+    	}
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::Connection
+// Returns the connection.
+// -----------------------------------------------------------------------------
+//
+RConnection& CCRConnection::Connection ( void ) 
+    {
+    return iConnection; 
+    }
+    
+// -----------------------------------------------------------------------------
+// CCRConnection::State
+// Returns state of connection.
+// -----------------------------------------------------------------------------
+//
+CCRConnection::TConnectionState CCRConnection::State( void ) const 
+    {
+    return iState;  
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::BearerType
+// -----------------------------------------------------------------------------
+//
+TConnMonBearerType CCRConnection::BearerType() const
+    {
+    return iBearerType;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::RegisterObserver
+// -----------------------------------------------------------------------------
+//
+TInt CCRConnection::RegisterObserver( MCRConnectionObserver* aObserver )
+    {
+    LOG( "CCRConnection::RegisterObserver" );
+    return iObservers.Append( aObserver );
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::UnregisterObserver
+// -----------------------------------------------------------------------------
+//
+TInt CCRConnection::UnregisterObserver( MCRConnectionObserver* aObserver )
+    {
+    LOG( "CCRConnection::UnregisterObserver" );
+    TInt pos = iObservers.Find( aObserver );
+    if ( pos < KErrNone ) 
+        {
+        return pos;
+        }
+
+    iObservers.Remove( pos );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::GetHeuristic
+// -----------------------------------------------------------------------------
+//
+TBool CCRConnection::GetHeuristic( TConnectionHeuristic aHeuristic )
+    {
+    TInt bit( 1 << ( TInt )aHeuristic );
+    return ( TBool )( iHeuristics & bit );
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::SetHeuristic
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::SetHeuristic( TConnectionHeuristic aHeuristic, TBool aValue )
+    {
+    TInt mask( 1 << ( TInt )aHeuristic );
+    if ( aValue )
+        {
+        iHeuristics |= mask;
+        }
+    else
+        {
+        iHeuristics &= ~mask;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::EventL
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::EventL( const CConnMonEventBase& aEvent )
+    {
+	// bearer change events
+    if( aEvent.EventType()==EConnMonBearerChange && iState==EOpen )
+        {
+        // IMPORTANT: EConnMonBearerChange event report changes in *some* connection, not
+        // necessarly ours and aEvent.ConnectionId() doest *not* contain plain 'connection id',
+        // it has 'bearer id'. So make a new bearertype query to make sure it's ours.
+        LOG2( "CCRConnection::EventL: bearer changed, id=%d, bearer=%d", 
+            aEvent.ConnectionId(), ( ( CConnMonBearerChange* )( &aEvent) )->Bearer() );
+
+        // Cancel ongoing requests
+        if ( IsActive() )
+            {
+            Cancel();
+            }
+
+        iState = CCRConnection::EFindingBearer;
+        iConMon.GetIntAttribute( iCurrentConnectionId, 0, KBearer,
+                                 ( TInt& )iNewBearerType, iStatus );
+		SetActive();
+        }
+    // other unhandled events
+    else
+        {
+        LOG2( "CCRConnection::EventL: unknown event=%d, connection=%d",
+                              aEvent.EventType(), aEvent.ConnectionId() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::IsBearerWLANor3G
+// -----------------------------------------------------------------------------
+//
+TBool CCRConnection::IsBearerWLANor3G( TConnMonBearerType aBearer )
+    {
+    return aBearer == EBearerWCDMA    ||  // from CIptvNetworkEngine::IsBearer3GOrWLAN,
+           aBearer == EBearerWLAN     ||  // EBearerLAN is returned by emulator
+           aBearer == EBearerCDMA2000 ||
+           aBearer == EBearerLAN;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::MaximumBandwidth
+// -----------------------------------------------------------------------------
+//
+TInt CCRConnection::MaximumBandwidth()
+    {
+    // Determine bandwidth based on bearer or from ConnectionMonitor attributes
+    // (KMaximumBitrateDownlink, KGuaranteedBitrateDownlink) when QoS is supported
+    TConnMonBearerType bearer = BearerType();
+    TInt bandwidth( 0 );
+
+    switch( bearer )
+        {
+        case EBearerGPRS:
+            bandwidth = KCRBandwidthGPRS;
+            break;
+        
+        case EBearerEdgeGPRS:
+            bandwidth = KCRBandwidthEdgeGPRS;
+            break;
+        
+        case EBearerWCDMA:
+            bandwidth = KCRBandwidthWCDMA;
+            break;
+        
+        case EBearerWLAN:
+            bandwidth = KCRBandwidthWLAN;
+            break;
+        
+        case EBearerLAN:
+            bandwidth = KCRBandwidthLAN;
+            break;
+        
+        default:
+            // None
+            break;
+        }
+
+    return bandwidth;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::FindApL
+// Request succesful completion.
+// -----------------------------------------------------------------------------
+//
+TInt CCRConnection::FindApL()
+    {
+    CloseRConnection();
+    TInt err( iConnection.Open( iSockServer ) );
+    if ( err )
+        {
+        LOG1( "CCRConnection::FindApL(), Open iConnection err: %d", err );
+        return err;
+        }
+    
+    // Connections
+    TUint foundConnections( 0 );
+    err = iConnection.EnumerateConnections( foundConnections );
+    if ( err )
+        {
+        LOG1( "CCRConnection::FindApL(), EnumerateConnections fail: %d", err );
+        return err;
+        }
+
+    // Active connection found
+    TUint conId( 0 ); // connection id
+    TUint subId( 0 ); // subconnection id
+    TUint conToUse( 0 );
+    for ( TInt i( 1 ); i <= foundConnections && !err; i++ )
+        {
+        err = iConMon.GetConnectionInfo( i, conId, subId );
+        if ( !err && conId == iCurrentConnectionId ) 
+            {
+            conToUse = i;   
+            i = foundConnections + 1; // break from loop
+            }
+        }
+    if ( err )
+        {
+        LOG1( "CCRConnection::FindApL() GetConnectionInfo loop err: %d", err );
+        return err;
+        }
+    
+    // Connection info
+    TPckgBuf<TConnectionInfo> info;
+    err = iConnection.GetConnectionInfo( conToUse, info );
+    if ( err )
+        {
+        LOG1( "CCRConnection::FindApL(), GetConnectionInfo 2 fail: %d", err );
+        return err;
+        }
+
+    // Attach
+    err = iConnection.Attach( info, RConnection::EAttachTypeNormal );
+    if ( err )
+        {
+        LOG1( "CCRConnection::FindApL(), Attach failed: %d", err );
+        }
+    
+    // Bearer type
+    iState = CCRConnection::EFindingBearer;
+    iBearerType = EBearerUnknown;
+    iConMon.GetIntAttribute( 
+        iCurrentConnectionId, 0, KBearer, ( TInt& )iNewBearerType, iStatus );
+    SetActive();
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::FindBearerL
+// Request succesful completion.
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::FindBearerL()
+    {
+    LOG2( "CCRConnection::FindBearerL(), iCurrentConnectionId: %d, iNewBearerType: %d",
+        iCurrentConnectionId, iNewBearerType );
+
+    iState = CCRConnection::EOpen;
+    TBool was3g( IsBearerWLANor3G( iBearerType ) );
+    TBool is3g( IsBearerWLANor3G( iNewBearerType ) );
+    TBool genChanged( was3g^is3g );
+    TBool justConnected( iBearerType == EBearerUnknown );
+    iBearerType = iNewBearerType;
+
+    // Notify if connection has just gone up
+    if ( justConnected )
+        {
+        // Broadcast IapUp&Running for observers
+        MCRConnectionObserver::TCRConnectionStatus status;
+        status = MCRConnectionObserver::ECRAttachCompleted;
+        for ( TInt i( 0 ); i < iObservers.Count(); i++ )
+            {
+            iObservers[i]->ConnectionStatusChange( 0, status, iStatus.Int() );
+            }
+        }
+
+    // Notify if connection has just gone up or generation changed
+    if ( genChanged )
+        {
+        // Broadcast IapUp&Running for observers
+        MCRConnectionObserver::TCRConnectionStatus status;
+        status = MCRConnectionObserver::ECRBearerChanged;
+        for( TInt i=0 ; i<iObservers.Count() ; i++ )
+            {
+            iObservers[i]->ConnectionStatusChange( 0, status, iStatus.Int() );
+            }
+        }
+    if ( iConnection.SubSessionHandle() )
+        {
+        // Request connection progress notifications from RConnection
+        iConMonProgressNotifyPending = ETrue;
+        iConnection.ProgressNotification( iNotification, iStatus );
+        SetActive();    
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCRConnection::NotificationL
+// Request succesful completion.
+// -----------------------------------------------------------------------------
+//
+void CCRConnection::NotificationL()
+    {
+    TNifProgress notification = iNotification();
+    LOG2( "CCRConnection::NotificationL stage: %d err: %d",
+        ( TInt )( notification.iStage ), ( TInt )( notification.iError ) );
+
+    if ( notification.iError != KErrNone ) 
+        {
+        // Notify UI
+        iState = CCRConnection::EIdle;
+    
+        MCRConnectionObserver::TCRConnectionStatus status;
+        status = MCRConnectionObserver::ECRIapDown;
+        for ( TInt i( 0 ); i < iObservers.Count(); i++ )
+            {
+            iObservers[i]->ConnectionStatusChange( 0, status, notification.iError );
+            }
+    
+        if ( iConnection.SubSessionHandle() )
+            {
+            iConnection.CancelProgressNotification();
+            iConMonProgressNotifyPending = EFalse;
+            CloseRConnection();
+            }
+        
+        iCurrentConnectionId = 0;
+        iBearerType = EBearerUnknown;   
+        }
+    else
+        {
+        switch ( notification.iStage ) 
+            {
+            case KLinkLayerOpen:
+                // this means we're open
+                break;
+    
+            case KConfigDaemonStartingDeregistration:
+            case KConfigDaemonUnloading:
+            case KConfigDaemonUnloaded:
+            case KLinkLayerClosed:
+                // And we're closed or closing
+                break;
+    
+            default:
+                // Do nothing in rest of the cases
+                break;
+            }
+    
+        if ( iConnection.SubSessionHandle() )
+            {
+            iConnection.ProgressNotification( iNotification, iStatus );
+            iConMonProgressNotifyPending = ETrue;
+            SetActive();    
+            }
+        }
+    }
+
+//  End of File