diff -r 826cea16efd9 -r 13a33d82ad98 dvrengine/CommonRecordingEngine/src/CCRConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dvrengine/CommonRecordingEngine/src/CCRConnection.cpp Wed Sep 01 12:20:37 2010 +0100 @@ -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 +#include +#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 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 ; iConnectionStatusChange( 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