--- /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