diff -r 000000000000 -r 5a93021fdf25 connectionmonitoring/connmon/connectionmonitor/src/ConnMonNoti.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectionmonitoring/connmon/connectionmonitor/src/ConnMonNoti.cpp Thu Dec 17 08:55:21 2009 +0200 @@ -0,0 +1,2395 @@ +/* +* Copyright (c) 2002-2007 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: Event notifiers (active objects). +* +*/ + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif +#include +#include +#include + +#include "ConnMonServ.h" +#include "ConnMonSess.h" +#include "CEventQueue.h" +#include "ConnMonIAP.h" +#include "ConnMonNoti.h" +#include "ConnMonAvailabilityManager.h" +#include "log.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CConnUpDownNotifier::CConnUpDownNotifier +// ----------------------------------------------------------------------------- +// +CConnUpDownNotifier::CConnUpDownNotifier( + CConnMonServer* aServer ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ) + { + } + +// ----------------------------------------------------------------------------- +// CConnUpDownNotifier::ConstructL +// ----------------------------------------------------------------------------- +// +void CConnUpDownNotifier::Construct() + { + //LOGENTRFN("CConnUpDownNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CConnUpDownNotifier") + //LOGEXITFN("CConnUpDownNotifier::Construct()") + } + +// Destructor +CConnUpDownNotifier::~CConnUpDownNotifier() + { + Cancel(); + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CConnUpDownNotifier::Receive +// Requests a new event (connection up/down) from RConnection +// ----------------------------------------------------------------------------- +// +void CConnUpDownNotifier::Receive() + { + if ( IsActive() ) + { + Cancel(); + } + + iServer->Iap()->Rconnection()->AllInterfaceNotification( iInfoBuf, iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CConnUpDownNotifier::DoCancel +// Cancels the request from RConnection. +// ----------------------------------------------------------------------------- +// +void CConnUpDownNotifier::DoCancel() + { + if ( IsActive() ) + { + iServer->Iap()->Rconnection()->CancelAllInterfaceNotification(); + } + } + +// ----------------------------------------------------------------------------- +// CConnUpDownNotifier::RunL +// Handles the event that has arrived from RConnection +// ----------------------------------------------------------------------------- +// +void CConnUpDownNotifier::RunL() + { + //LOGENTRFN("CConnUpDownNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CConnUpDownNotifier, status <%d>", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + iErrorCounter++; + if ( iErrorCounter > KConnMonEventErrorThreshold ) + { + LOGIT1("Over %d consecutive errors, stopping", KConnMonEventErrorThreshold) + return; + } + } + else + { + iErrorCounter = 0; + // Send event to clients + TInt err( KErrNone ); + TBearerInfo bearerInfo; + TConnInfo connInfo( + iInfoBuf().iConnectionInfo.iIapId, + iInfoBuf().iConnectionInfo.iNetId, + 0, + 0, + bearerInfo ); + + TInt listeners( iServer->NumberOfListeners() ); + LOGIT3("CConnUpDownNotifier, %d listeners, iap id %d, net id %d", + listeners, connInfo.iIapId, connInfo.iNetId) + iEventInfo.Reset(); + + if ( iInfoBuf().iState == EInterfaceUp ) + { + // Add to the connection table and fill in the new connectioId to connInfo + TRAPD( ret, ( err = iServer->Iap()->AddConnectionL( connInfo ) ) ); + + if ( ( ret != KErrNone ) || ( err != KErrNone ) ) + { + LOGIT2("SERVER: FAILED to add a new connection <%d>,<%d>", ret, err) + Receive(); + return; // Can't leave + } + + // Send event to all clients that are listening + if ( listeners > 0) + { + iEventInfo.iEventType = EConnMonCreateConnection; + iEventInfo.iConnectionId = connInfo.iConnectionId; + + iServer->EventQueue()->Add( iEventInfo ); + } + + LOGIT1("SERVER: EVENT -> connection %d created.", connInfo.iConnectionId) + } + else if ( iInfoBuf().iState == EInterfaceDown ) + { + if ( listeners == 0 ) + { + // Remove from the connection array. Note. when the notifications + // are ON event handlers will remove the connection from the array. + iServer->Iap()->RemoveConnection( connInfo ); + } + else + { + TBool alreadyNotified( EFalse ); + + // This updates the correct 'iConnectionId' and 'iBearer' to connInfo + TInt ret = iServer->Iap()->GetDeleteNotifyStatus( connInfo, alreadyNotified ); + + if ( ret == KErrNone ) + { + CSubConnUpDownNotifier* subConnUpDownNotifier = 0; + + ret = iServer->Iap()->GetSubConnUpDownNotifier( + connInfo.iConnectionId, + &subConnUpDownNotifier ); + + if ( ret == KErrNone ) + { + subConnUpDownNotifier->SetInterfaceClosed(); + + if ( !subConnUpDownNotifier->DeleteSent() ) + { + TNifProgress progress; + err = iServer->Iap()->LastProgressError( + connInfo.iConnectionId, + progress ); + + if ( progress.iError == KErrDisconnected ) + { + // Enable WLAN scan for the next IAP availability check + // because the current bearer has been lost (-36). MPM needs + // a fresh list of available iaps on connection closure. + iServer->Iap()->EnableWlanScan(); + } + + // Progress and subconn notifiers have died and no delete has been sent + subConnUpDownNotifier->SendDeletedEvent(); + } + else + { + // Delete has been sent. Just remove from internal table. + iServer->Iap()->RemoveConnection( connInfo ); + } + } + } + + } + LOGIT3("SERVER: EVENT (allinterface) -> connection %d (%d, %d) closed.", + connInfo.iConnectionId, connInfo.iIapId, connInfo.iNetId) + } + else + { + LOGIT("SERVER: Unknown event") + Receive(); + return; + } + + LOGIT("CConnUpDownNotifier::RunL triggered HandleAvailabilityChange()") + iServer->AvailabilityManager()->HandleAvailabilityChange(); + } + // New request + Receive(); + //LOGEXITFN("CConnUpDownNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CDataNotifier::CDataNotifier +// ----------------------------------------------------------------------------- +// +CDataNotifier::CDataNotifier( + CConnMonServer* aServer, + RConnection* aConnection, + const TUint& aConnectionId, + const TUint& aSubConnectionId, + const TInt& aDirection ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iConnection( aConnection ), + iConnectionId( aConnectionId), + iSubConnectionId( aSubConnectionId ), + iDirection( aDirection ), + iVolume( 0 ), + iPckgVolume( iVolume ) + { + } + +// ----------------------------------------------------------------------------- +// CDataNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CDataNotifier::Construct() + { + //LOGENTRFN("CDataNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CDataNotifier") + //LOGEXITFN("CDataNotifier::Construct()") + } + +// Destructor +CDataNotifier::~CDataNotifier() + { + Cancel(); + + iServer = NULL; + iConnection = NULL; + } + +// ----------------------------------------------------------------------------- +// CDataNotifier::Receive +// Requests a new event (data transferred) from RConnection +// ----------------------------------------------------------------------------- +// +void CDataNotifier::Receive() + { + // Don't make a new request if previous + // status indicates that connection is closing + if ( iStatus == KErrCancel ) + { + return; + } + + if ( IsActive() ) + { + return; + } + + iVolume = 0; + + if ( iDirection == EDownlink ) + { + iServer->CalculateThreshold( + iConnectionId, + EDownlinkThreshold, + iThreshold ); + + if ( iThreshold > 0 ) + { + iConnection->DataReceivedNotificationRequest( + iThreshold, + iPckgVolume, + iStatus ); + SetActive(); + } + } + else + { + iServer->CalculateThreshold( + iConnectionId, + EUplinkThreshold, + iThreshold ); + if ( iThreshold > 0 ) + { + iConnection->DataSentNotificationRequest( + iThreshold, + iPckgVolume, + iStatus ); + SetActive(); + } + } + } + +// ----------------------------------------------------------------------------- +// CDataNotifier::DoCancel +// Cancels the request from RConnection. +// ----------------------------------------------------------------------------- +// +void CDataNotifier::DoCancel() + { + if ( IsActive() ) + { + if ( iDirection == EDownlink ) + { + iConnection->DataReceivedNotificationCancel(); + } + else + { + iConnection->DataSentNotificationCancel(); + } + } + } + +// ----------------------------------------------------------------------------- +// CDataNotifier::RunL +// Handles the event that has arrived from RConnection +// ----------------------------------------------------------------------------- +// +void CDataNotifier::RunL() + { + //LOGENTRFN("CDataNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CDataNotifier, status %d", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + //LOGIT2("SERVER: Data volume event FAILED <%d>, id <%d>", iStatus.Int(), iConnectionId ) + iErrorCounter++; + if ( iErrorCounter > KConnMonEventErrorThreshold ) + { + LOGIT1("Over %d consecutive errors, stopping", KConnMonEventErrorThreshold) + return; + } + } + else + { + iErrorCounter = 0; + iEventInfo.Reset(); + + // Send event(s) to clients + iEventInfo.iConnectionId = iConnectionId; + iEventInfo.iSubConnectionId = iSubConnectionId; + iEventInfo.iData = iPckgVolume(); + + if ( iDirection == EDownlink ) + { + iEventInfo.iEventType = EConnMonDownlinkDataThreshold; + LOGIT2("SERVER: EVENT -> Downlink data <%d>, id <%d>", iEventInfo.iData, iEventInfo.iConnectionId ) + } + else + { + iEventInfo.iEventType = EConnMonUplinkDataThreshold; + LOGIT2("SERVER: EVENT -> Uplink data <%d>, id <%d>", iEventInfo.iData, iEventInfo.iConnectionId ) + } + + iServer->EventQueue()->Add( iEventInfo ); + } + // New request + Receive(); + //LOGEXITFN("CDataNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CProgressNotifier::CProgressNotifier +// Priority is set to 10. Progress notifier must have higher priority than +// connection up/down notifier because otherwise connection delete event will +// arrive before status reaches KLinkLayerClosed. +// ----------------------------------------------------------------------------- +// +CProgressNotifier::CProgressNotifier( + CConnMonServer* aServer, + RConnection* aConnection, + const TUint& aConnectionId, + const TUint& aSubConnectionId ) + : + CActive( EConnMonPriorityHigh ), + iServer( aServer ), + iConnection( aConnection ), + iConnectionId( aConnectionId), + iSubConnectionId( aSubConnectionId ), + iFilter( KNoFiltering ) + { + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CProgressNotifier::Construct() + { + //LOGENTRFN("CProgressNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CProgressNotifier") + //LOGEXITFN("CProgressNotifier::Construct()") + } + +// Destructor +CProgressNotifier::~CProgressNotifier() + { + if ( IsActive() ) + { + Cancel(); + } + + iServer = NULL; + iConnection = NULL; + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::Receive +// Requests a new event (connection status changed) from RConnection +// ----------------------------------------------------------------------------- +// +void CProgressNotifier::Receive() + { + if ( IsActive() ) + { + Cancel(); + } + + iInfoBuf().iStage = 0; + iInfoBuf().iError = 0; + + iConnection->ProgressNotification( iInfoBuf, iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::Receive +// Requests a new event (connection status changed) from RConnection +// Uses filtering until status reaches aFilter +// ----------------------------------------------------------------------------- +// +void CProgressNotifier::Receive( const TInt aFilter ) + { + iFilter = aFilter; + Receive(); + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::IsAuthDelete +// ETrue if the user has deactivated the connection +// by using Connection Monitor or if the applications issued +// RConnection::Stop( RConnection::EStopAuthoritative ) +// ----------------------------------------------------------------------------- +// +TBool CProgressNotifier::IsAuthDelete() + { + if ( iInfoBuf().iError == KErrConnectionTerminated ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::CanReconnect +// ETrue if might reconnect after closing. +// ----------------------------------------------------------------------------- +// +TBool CProgressNotifier::CanReconnect() const + { + // Reconnect is disabled for the moment + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::DoCancel +// Cancels the request from RConnection. +// ----------------------------------------------------------------------------- +// +void CProgressNotifier::DoCancel() + { + if ( IsActive() ) + { + iConnection->CancelProgressNotification(); + } + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::SendClosedEvent +// ----------------------------------------------------------------------------- +// +void CProgressNotifier::SendClosedEvent() + { + iEventInfo.Reset(); + + iEventInfo.iEventType = EConnMonConnectionStatusChange; + iEventInfo.iConnectionId = iConnectionId; + iEventInfo.iSubConnectionId = iSubConnectionId; + iEventInfo.iData = KLinkLayerClosed; + + // Send event to all clients that are listening + iServer->EventQueue()->Add( iEventInfo ); + } + +// ----------------------------------------------------------------------------- +// CProgressNotifier::RunL +// Handles the event that has arrived from RConnection +// ----------------------------------------------------------------------------- +// +void CProgressNotifier::RunL() + { + //LOGENTRFN("CProgressNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CProgressNotifier, status %d", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + LOGIT2("SERVER: connection status event FAILED <%d>, id %d", iStatus.Int(), iConnectionId) + } + else + { + iEventInfo.Reset(); + + if ( iInfoBuf().iStage != static_cast< TInt >( iEventInfo.iData ) ) + { + // Send only new stage info to clients + iEventInfo.iEventType = EConnMonConnectionStatusChange; + iEventInfo.iConnectionId = iConnectionId; + iEventInfo.iSubConnectionId = iSubConnectionId; + iEventInfo.iData = iInfoBuf().iStage; + + LOGIT3("SERVER: EVENT -> Connection %d, status %d <%d>", + iEventInfo.iConnectionId, iEventInfo.iData, iInfoBuf().iError) + + if ( ( iFilter == KNoFiltering ) || ( iInfoBuf().iStage > iFilter ) ) + { + // Send event to all clients that are listening + iServer->EventQueue()->Add( iEventInfo ); + + // Start other event watchers when the connection status reaches + // KLinkLayerOpen for the first time. + if ( iInfoBuf().iStage == KLinkLayerOpen ) + { + // Start subconnection up/down notifier when stage reaches KLinkLayerOpen + CSubConnUpDownNotifier* subConnUpDownNotifier = 0; + + TInt err = iServer->Iap()->GetSubConnUpDownNotifier( + iConnectionId, + &subConnUpDownNotifier ); + + if ( KErrNone == err ) + { + if ( !subConnUpDownNotifier->IsActive() ) + { + subConnUpDownNotifier->Receive(); + } + } + + // Start activity notifier when stage reaches KLinkLayerOpen + TRAPD( ret, ( iServer->Iap()->LaunchActivityNotifierL( iConnectionId ) ) ); + + if ( ret != KErrNone ) + { + LOGIT1("SERVER: FAILED to start activity notifier <%d>", ret) + return; // Can't leave + } + + // Start data (uplink & downlink) notifiers when stage reaches KLinkLayerOpen + iServer->Iap()->LaunchDataNotifiers( iConnectionId ); + + ret = iServer->Iap()->LaunchBearerNotifier( iConnectionId ); + if ( ret != KErrNone ) + { + LOGIT1("SERVER: FAILED to start bearer(new) notifier <%d>", ret) + } + } + + iFilter = KNoFiltering; + } + else + { + LOGIT("SERVER: This is old info. Packet was filtered out.") + } + } + + if ( iInfoBuf().iError == KErrNone ) + { + // New request + Receive(); + } + else + { + // Connection is closing. + CSubConnUpDownNotifier* subConnUpDownNotifier = 0; + TInt err = iServer->Iap()->GetSubConnUpDownNotifier( + iConnectionId, + &subConnUpDownNotifier ); + + if ( KErrNone == err ) + { + // Subconn down notifier has stopped and allinterface closed event has arrived + if ( !subConnUpDownNotifier->IsActive() ) + { + subConnUpDownNotifier->SendDeletedEvent(); + } + } + + if ( iInfoBuf().iError == KErrDisconnected ) + { + // Enable WLAN scan when IAP availability is check for the + // next time because current bearer has been lost (-36). + // MPM needs a fresh list of available iaps. + iServer->Iap()->EnableWlanScan(); + } + } + } + //LOGEXITFN("CProgressNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CNetwStatusNotifier::CNetwStatusNotifier +// ----------------------------------------------------------------------------- +// +CNetwStatusNotifier::CNetwStatusNotifier( + CConnMonServer* aServer ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ) + { + } + +// ----------------------------------------------------------------------------- +// CNetwStatusNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CNetwStatusNotifier::Construct() + { + //LOGENTRFN("CNetwStatusNotifier::Construct()") + + CActiveScheduler::Add( this ); + TInt ret = iServer->Iap()->PacketService()->GetStatus( iPacketStatus ); + if ( ret != KErrNone ) + { + iPacketStatus = RPacketService::EStatusUnattached; + } + LOGIT("Created CNetwStatusNotifier") + + //LOGEXITFN("CNetwStatusNotifier::Construct()") + } + +// ----------------------------------------------------------------------------- +// CNetwStatusNotifier::NewL +// ----------------------------------------------------------------------------- +// +CNetwStatusNotifier* CNetwStatusNotifier::NewL( CConnMonServer* aServer ) + { + CNetwStatusNotifier* self = new( ELeave ) CNetwStatusNotifier( aServer ); + self->Construct(); + return self; + } + +// Destructor +CNetwStatusNotifier::~CNetwStatusNotifier() + { + Cancel(); + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CNetwStatusNotifier::Receive +// Requests a new event (network status changed) from ETel +// ----------------------------------------------------------------------------- +// +void CNetwStatusNotifier::Receive() + { + if ( IsActive() ) + { + return; + } + + iServer->Iap()->PacketService()->NotifyStatusChange( iStatus, iPacketStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CNetwStatusNotifier::DoCancel +// Cancels the request from ETel. +// ----------------------------------------------------------------------------- +// +void CNetwStatusNotifier::DoCancel() + { + if ( IsActive() ) + { + iServer->Iap()->PacketService()->CancelAsyncRequest( EPacketNotifyStatusChange ); + } + } + +// ----------------------------------------------------------------------------- +// CNetwStatusNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CNetwStatusNotifier::RunL() + { + //LOGENTRFN("CNetwStatusNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CNetwStatusNotifier, status %d", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + LOGIT1("SERVER: network status event FAILED <%d>", iStatus.Int()) + } + else + { + iEventInfo.Reset(); + + iEventInfo.iEventType = EConnMonNetworkStatusChange; + iEventInfo.iSubConnectionId = 0; + iEventInfo.iData = iServer->Iap()->CalculateNetworkStatus( iPacketStatus ); + + // Find out bearer ID. + iServer->Iap()->GetBearerId( iEventInfo.iConnectionId ); + + LOGIT2("SERVER: EVENT -> Network status %d, id %d", iEventInfo.iData, iEventInfo.iConnectionId) + + // Send event to all clients that are listening + iServer->EventQueue()->Add( iEventInfo ); + + LOGIT("CNetwStatusNotifier::RunL triggered HandleAvailabilityChange()") + iServer->AvailabilityManager()->HandleAvailabilityChange(); + } + + // New request + Receive(); + //LOGEXITFN("CNetwStatusNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CNetwRegistrationNotifier::CNetwRegistrationNotifier +// Notifies changes in network registration status. +// Notifies also changes in CSD bearer availability and CSD IAP availability. +// ----------------------------------------------------------------------------- +// +CNetwRegistrationNotifier::CNetwRegistrationNotifier( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iMobilePhone( aMobilePhone ) + { + } + +// ----------------------------------------------------------------------------- +// CNetwRegistrationNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CNetwRegistrationNotifier::Construct() + { + //LOGENTRFN("CNetwRegistrationNotifier::Construct()") + CActiveScheduler::Add( this ); + + iRegistration = RMobilePhone::ERegistrationUnknown; + iEventInfo.iData = RMobilePhone::ERegistrationUnknown; + + TBool cellSupportsCSD( EFalse ); + + // Is CSD supported both by the cell and the phone + iServer->Iap()->GetBearerSupportInfo( + EBearerIdCSD, + cellSupportsCSD, + iPhoneSupportsCSD ); + + if ( cellSupportsCSD && iPhoneSupportsCSD ) + { + iCSDSupported = ETrue; + } + LOGIT("Created CNetwRegistrationNotifier") + + //LOGEXITFN("CNetwRegistrationNotifier::Construct()") + } + +// ----------------------------------------------------------------------------- +// CNetwRegistrationNotifier::NewL +// ----------------------------------------------------------------------------- +// +CNetwRegistrationNotifier* CNetwRegistrationNotifier::NewL( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + { + CNetwRegistrationNotifier* self = new( ELeave ) CNetwRegistrationNotifier( + aServer, + aMobilePhone ); + + self->Construct(); + return self; + } + +// Destructor +CNetwRegistrationNotifier::~CNetwRegistrationNotifier() + { + Cancel(); + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CNetwRegistrationNotifier::Receive +// Requests a new event (network registration changed) from ETel +// ----------------------------------------------------------------------------- +// +void CNetwRegistrationNotifier::Receive() + { + if ( IsActive() ) + { + return; + } + + iMobilePhone.NotifyNetworkRegistrationStatusChange( iStatus, iRegistration ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CNetwRegistrationNotifier::DoCancel +// Cancels the request from ETel. +// ----------------------------------------------------------------------------- +// +void CNetwRegistrationNotifier::DoCancel() + { + if ( IsActive() ) + { + iMobilePhone.CancelAsyncRequest( EMobilePhoneNotifyNetworkRegistrationStatusChange ); + } + } + +// ----------------------------------------------------------------------------- +// CNetwRegistrationNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CNetwRegistrationNotifier::RunL() + { + //LOGENTRFN("CNetwRegistrationNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CNetwRegistrationNotifier, status <%d>", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + LOGIT1("SERVER: network registration event FAILED <%d>", iStatus.Int()) + } + else + { + TUint value( RMobilePhone::ERegistrationUnknown ); + + value = iServer->Iap()->CalculateNetworkRegistration( iRegistration ); + + // Is this a new registration status value + if ( iEventInfo.iData != value ) + { + // Send Network registration status changed event when FeatureFlag is ON + if ( FeatureManager::FeatureSupported( KFeatureIdNetworkRegistration ) ) + { + iEventInfo.Reset(); + + iEventInfo.iData = value; + iEventInfo.iEventType = EConnMonNetworkRegistrationChange; + + // Find out bearer ID. + iServer->Iap()->GetBearerId( iEventInfo.iConnectionId ); + + if ( iEventInfo.iConnectionId == EBearerIdGPRS ) + { + iEventInfo.iConnectionId = EBearerIdGSM; + } + + iServer->EventQueue()->Add( iEventInfo ); + } + + LOGIT2("SERVER: EVENT -> Network registration %d, id %d", iEventInfo.iData, iEventInfo.iConnectionId) + + if ( iPhoneSupportsCSD ) + { + iEventInfo.Reset(); + iEventInfo.iEventType = EConnMonBearerAvailabilityChange; + + if ( iRegistration == RMobilePhone::ERegisteredBusy || + iRegistration == RMobilePhone::ERegisteredOnHomeNetwork || + iRegistration == RMobilePhone::ERegisteredRoaming ) + { + iEventInfo.iData = ETrue; + } + + if ( static_cast< TUint >( iCSDSupported ) != iEventInfo.iData ) + { + // Find out bearer ID for CSD. + iServer->Iap()->GetBearerId( iEventInfo.iConnectionId, ETrue ); + + // Send the event only if threshold is set by some of the clients. + TUint threshold( 0 ); + + iServer->CalculateThreshold( + EBearerIdAll, + EBearerAvailabilityThreshold, + threshold ); + + if ( threshold > 0 ) + { + iServer->EventQueue()->Add( iEventInfo ); + } + + iCSDSupported = iEventInfo.iData; + + LOGIT2("SERVER: EVENT -> Bearer availability changed: data %d, id %d", iEventInfo.iData, iEventInfo.iConnectionId) + + // Send CSD IAP availability event only when packet services are not available. + // Otherwise CSD IAP availability information goes along with packet IAP event. + TUint32 capsPhone( 0 ); + TInt err = iMobilePhone.GetMultimodeCaps( capsPhone ); + } + } + + // Store to compare next event correctly + iEventInfo.iData = value; + } + LOGIT("CNetwRegistrationNotifier::RunL triggered HandleAvailabilityChange()") + iServer->AvailabilityManager()->HandleAvailabilityChange(); + } + // New request + Receive(); + //LOGEXITFN("CNetwRegistrationNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CBearerNotifier::CBearerNotifier +// Notifies when the bearer changes from EGPRS to GPRS on vice versa. +// This information is cell specific. +// ----------------------------------------------------------------------------- +// +CBearerNotifier::CBearerNotifier( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iMobilePhone( aMobilePhone ), + iGprsInfo(), + iGprsInfoPckg( iGprsInfo ), + iErrorCounter( 0 ) + { + } + +// ----------------------------------------------------------------------------- +// CBearerNotifier::ConstructL +// ----------------------------------------------------------------------------- +// +void CBearerNotifier::ConstructL() + { + //LOGENTRFN("CBearerNotifier::ConstructL()") + CActiveScheduler::Add( this ); + + // Open ETel custom API + TInt ret = iCustomApi.Open( iMobilePhone ); + if ( ret != KErrNone ) + { + LOGIT1("ERROR starting bearer notifier. RMmCustomAPI.Open() failed <%d>", ret) + User::Leave( ret ); + } + + iEventInfo.iData = EBearerUnknown; + LOGIT("Created CBearerNotifier") + + //LOGEXITFN("CBearerNotifier::ConstructL()") + } + +// ----------------------------------------------------------------------------- +// CBearerNotifier::NewL +// ----------------------------------------------------------------------------- +// +CBearerNotifier* CBearerNotifier::NewL( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + { + CBearerNotifier* self = new( ELeave ) CBearerNotifier( + aServer, + aMobilePhone ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// Destructor +CBearerNotifier::~CBearerNotifier() + { + Cancel(); + + // Close ETel custom API + iCustomApi.Close(); + + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CBearerNotifier::Receive +// Requests a new event (bearer changed) from ETel Custom API +// ----------------------------------------------------------------------------- +// +void CBearerNotifier::Receive() + { + if ( IsActive() ) + { + return; + } + + iCustomApi.NotifyEGprsInfoChange( iStatus, iGprsInfoPckg ); + + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CBearerNotifier::DoCancel +// Cancels the request from ETel Custom API. +// ----------------------------------------------------------------------------- +// +void CBearerNotifier::DoCancel() + { + if ( IsActive() ) + { + iCustomApi.CancelAsyncRequest( ECustomNotifyEGprsInfoChange ); + } + } + +// ----------------------------------------------------------------------------- +// CBearerNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CBearerNotifier::RunL() + { + //LOGENTRFN("CBearerNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CBearerNotifier, status <%d>", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + iErrorCounter++; + if ( iErrorCounter > KConnMonEventErrorThreshold ) + { + LOGIT1("Over %d consecutive errors, stopping", KConnMonEventErrorThreshold) + //LOGEXITFN("CBearerNotifier::RunL()") + return; + } + } + else + { + iErrorCounter = 0; + LOGIT1("SERVER: CBearerNotifier: iGprsInfo <%d>", iGprsInfoPckg().iGprsInfo) + iEventInfo.Reset(); + + // Check that that we are in GSM mode. This event will be sent only in GSM mode. + RMobilePhone::TMobilePhoneNetworkMode mode( RMobilePhone::ENetworkModeUnknown ); + + TInt ret = iMobilePhone.GetCurrentMode( mode ); + + if ( ( ret == KErrNone ) && ( mode == RMobilePhone::ENetworkModeGsm ) ) + { + if ( iGprsInfoPckg().iGprsInfo == RMmCustomAPI::EEdgeGprs ) + { + iEventInfo.iData = EBearerEdgeGPRS; + } + else + { + iEventInfo.iData = EBearerGPRS; + } + + iEventInfo.iEventType = EConnMonBearerChange; + iEventInfo.iConnectionId = EBearerIdGPRS; + + iServer->EventQueue()->Add( iEventInfo ); + + LOGIT3("SERVER: EVENT -> Bearer changed: %d, data %d, id %d", iGprsInfoPckg().iGprsInfo, iEventInfo.iData, iEventInfo.iConnectionId) + + // New Impl. + iEventInfo.Reset(); + iEventInfo.iEventType = EConnMonBearerInfoChange; + iEventInfo.iConnectionId = EBearerIdAll; // means that this is not a connection related event + + if ( iGprsInfoPckg().iGprsInfo == RMmCustomAPI::EEdgeGprs ) + { + iEventInfo.iData = EBearerInfoEdgeGPRS; + } + else + { + iEventInfo.iData = EBearerInfoGPRS; + } + + iServer->EventQueue()->Add( iEventInfo ); + + LOGIT2("SERVER: EVENT -> Bearer info changed: %d, data %d", iGprsInfoPckg().iGprsInfo, iEventInfo.iData) + } + } + + // New request + Receive(); + //LOGEXITFN("CBearerNotifier::RunL()") + } + +// ----------------------------------------------------------------------------- +// CBearerNotifier::CWcdmaBearerNotifier +// Notifies when the bearer changes from Wcdma to Hsdpa on vice versa. +// This information is cell specific. +// ----------------------------------------------------------------------------- +// +CWcdmaBearerNotifier::CWcdmaBearerNotifier( + CConnMonServer* aServer, + RTelServer& aTelServer ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iTelServer( aTelServer ), + iNetInfo(), + iNetInfoPckg( iNetInfo ) + { + } + +// ----------------------------------------------------------------------------- +// CWcdmaBearerNotifier::ConstructL +// ----------------------------------------------------------------------------- +// +void CWcdmaBearerNotifier::ConstructL() + { + //LOGENTRFN("CWcdmaBearerNotifier::ConstructL()") + CActiveScheduler::Add( this ); + + iPreviousBearerInfo = EBearerInfoWCDMA; + iEventInfo.iData = EBearerUnknown; + + RTelServer::TPhoneInfo info; + User::LeaveIfError( iTelServer.GetPhoneInfo( 0, info ) ); + User::LeaveIfError( iMobilePhone.Open( iTelServer, info.iName ) ); + + LOGIT("Created CWcdmaBearerNotifier") + //LOGEXITFN("CWcdmaBearerNotifier::ConstructL()") + } + +// ----------------------------------------------------------------------------- +// CWcdmaBearerNotifier::NewL +// ----------------------------------------------------------------------------- +// +CWcdmaBearerNotifier* CWcdmaBearerNotifier::NewL( + CConnMonServer* aServer, + RTelServer& aTelServer ) + { + CWcdmaBearerNotifier* self = new( ELeave ) CWcdmaBearerNotifier( + aServer, + aTelServer ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// Destructor +CWcdmaBearerNotifier::~CWcdmaBearerNotifier() + { + Cancel(); + iServer = NULL; + + iMobilePhone.Close(); + } + +// ----------------------------------------------------------------------------- +// CWcdmaBearerNotifier::Receive +// Requests a new event (bearer changed) from ETel Custom API +// ----------------------------------------------------------------------------- +// +void CWcdmaBearerNotifier::Receive() + { + if ( IsActive() ) + { + return; + } + + iMobilePhone.NotifyCurrentNetworkChange( iStatus, iNetInfoPckg ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CWcdmaBearerNotifier::DoCancel +// Cancels the request from ETel Custom API. +// ----------------------------------------------------------------------------- +// +void CWcdmaBearerNotifier::DoCancel() + { + if ( IsActive() ) + { + iMobilePhone.CancelAsyncRequest( EMobilePhoneNotifyCurrentNetworkNoLocationChange ); + } + } + +// ----------------------------------------------------------------------------- +// CWcdmaBearerNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CWcdmaBearerNotifier::RunL() + { + //LOGENTRFN("CWcdmaBearerNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CWcdmaBearerNotifier, status <%d>", iStatus.Int()) + + if ( KErrNone != iStatus.Int() ) + { + LOGIT1("SERVER: CWcdmaBearerNotifier:Bearer changed event FAILED <%d>", iStatus.Int()) + } + else + { + LOGIT2("SERVER: CWcdmaBearerNotifier: EGPRS %d, HSDPA %d", + iNetInfoPckg().iEgprsAvailableIndicator, iNetInfoPckg().iHsdpaAvailableIndicator) + iEventInfo.Reset(); + + // Check that that we are in Wcdma mode. This event will be + // sent only in Wcdma mode. + RMobilePhone::TMobilePhoneNetworkMode mode( RMobilePhone::ENetworkModeUnknown ); + + TInt ret = iMobilePhone.GetCurrentMode( mode ); + LOGIT1("SERVER: CWcdmaBearerNotifier: current mode %d", mode) + + if ( ( KErrNone == ret ) && ( mode == RMobilePhone::ENetworkModeWcdma ) ) + { + iEventInfo.iEventType = EConnMonBearerInfoChange; + iEventInfo.iConnectionId = EBearerIdAll; // Means that this is not a connection related event + + if ( iNetInfoPckg().iHsdpaAvailableIndicator ) + { + iEventInfo.iData = EBearerInfoHSDPA; + } + else + { + iEventInfo.iData = EBearerInfoWCDMA; + } + + if ( iPreviousBearerInfo != iEventInfo.iData ) + { + iPreviousBearerInfo = (TConnMonBearerInfo)iEventInfo.iData; + + LOGIT1("SERVER: EVENT -> Wcdma bearer info changed, new bearer info %d", iEventInfo.iData) + iServer->EventQueue()->Add( iEventInfo ); + } + else + { + LOGIT1("SERVER: Wcdma bearer info NOT changed, bearer info %d", iEventInfo.iData) + } + } + } + // New request + Receive(); + //LOGEXITFN("CWcdmaBearerNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CModeNotifier::CModeNotifier +// Notifies when the bearer changes from 3G (WCDMA) to 2G (GPRS/EGPRS) or vice versa. +// ----------------------------------------------------------------------------- +// +CModeNotifier::CModeNotifier( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iMobilePhone( aMobilePhone ) + { + } + +// ----------------------------------------------------------------------------- +// CModeNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CModeNotifier::Construct() + { + //LOGENTRFN("CModeNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CModeNotifier") + //LOGEXITFN("CModeNotifier::Construct()") + } + +// ----------------------------------------------------------------------------- +// CModeNotifier::NewL +// ----------------------------------------------------------------------------- +// +CModeNotifier* CModeNotifier::NewL( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + { + CModeNotifier* self = new( ELeave ) CModeNotifier( aServer, aMobilePhone ); + self->Construct(); + return self; + } + +// Destructor +CModeNotifier::~CModeNotifier() + { + Cancel(); + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CModeNotifier::Receive +// Requests a new event (bearer changed) from ETel Custom API +// ----------------------------------------------------------------------------- +// +void CModeNotifier::Receive() + { + if ( IsActive() ) + { + return; + } + + iMobilePhone.NotifyModeChange( iStatus, iMode ); + + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CModeNotifier::DoCancel +// Cancels the request from ETel Custom API. +// ----------------------------------------------------------------------------- +// +void CModeNotifier::DoCancel() + { + if ( IsActive() ) + { + iMobilePhone.CancelAsyncRequest( EMobilePhoneNotifyModeChange ); + } + } + +// ----------------------------------------------------------------------------- +// CModeNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CModeNotifier::RunL() + { + //LOGENTRFN("CModeNotifier::RunL()") + TBool edgeCellDetected = EFalse; + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CModeNotifier, status %d", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + LOGIT1("SERVER: Mode changed event FAILED <%d>", iStatus.Int() ) + } + else + { + LOGIT1("SERVER: CModeNotifier: mode <%d>", iMode ) + iEventInfo.Reset(); + + iEventInfo.iEventType = EConnMonBearerChange; + + if ( iMode == RMobilePhone::ENetworkModeWcdma ) + { + iEventInfo.iConnectionId = EBearerIdWCDMA; + iEventInfo.iData = EBearerWCDMA; + } + else if ( iMode == RMobilePhone::ENetworkModeGsm ) + { + iEventInfo.iConnectionId = EBearerIdGPRS; + + edgeCellDetected = iServer->Iap()->IsEdgeCell(); + if ( edgeCellDetected ) + { + iEventInfo.iData = EBearerEdgeGPRS; + } + else + { + iEventInfo.iData = EBearerGPRS; + } + } + else + { + // Unknown + iEventInfo.iData = 0; + } + + if ( iEventInfo.iData != 0 ) + { + iServer->EventQueue()->Add( iEventInfo ); + + LOGIT3("SERVER: EVENT -> Mode changed: %d, data %d, id %d", + iMode, iEventInfo.iData, iEventInfo.iConnectionId) + } + + // New implemantation + iEventInfo.Reset(); + + iEventInfo.iEventType = EConnMonBearerInfoChange; + iEventInfo.iConnectionId = EBearerIdAll; // means that this is not a connection related event + + if ( iMode == RMobilePhone::ENetworkModeWcdma ) + { + iEventInfo.iData = (TUint)iServer->Iap()->HsxpaStatus(); + } + else if ( iMode == RMobilePhone::ENetworkModeGsm ) + { + if ( edgeCellDetected ) + { + iEventInfo.iData = EBearerInfoEdgeGPRS; + } + else + { + iEventInfo.iData = EBearerInfoGPRS; + } + } + else + { + // Unknown + iEventInfo.iData = 0; + } + + if ( iEventInfo.iData != 0 ) + { + iServer->EventQueue()->Add( iEventInfo ); + LOGIT2("SERVER: EVENT -> Mode changed(new impl.): %d, bearerinfo %d", iMode, iEventInfo.iData) + } + + TConnMonBearerInfo bI = ( TConnMonBearerInfo ) iEventInfo.iData; + iServer->Iap()->SendConnectionEvents( bI ); // BearerInfoChanged, BearerGroupChanged + } + + // New request + Receive(); + //LOGEXITFN("CModeNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CBearerAvailabilityNotifier::CBearerAvailabilityNotifier +// Notifies when GPRS/WCDMA bearer availability changes. +// Notifies also changes in GPRS/WCDMA IAP availability. +// ----------------------------------------------------------------------------- +// +CBearerAvailabilityNotifier::CBearerAvailabilityNotifier( + CConnMonServer* aServer ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ) + { + } + +// ----------------------------------------------------------------------------- +// CBearerAvailabilityNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CBearerAvailabilityNotifier::Construct() + { + //LOGENTRFN("CBearerAvailabilityNotifier::Construct()") + CActiveScheduler::Add( this ); + iRegStatus = RPacketService::EUnknown; + LOGIT("Created CBearerAvailabilityNotifier") + //LOGEXITFN("CBearerAvailabilityNotifier::Construct()") + } + +// ----------------------------------------------------------------------------- +// CBearerAvailabilityNotifier::NewL +// ----------------------------------------------------------------------------- +// +CBearerAvailabilityNotifier* CBearerAvailabilityNotifier::NewL( CConnMonServer* aServer ) + { + CBearerAvailabilityNotifier* self = new( ELeave ) CBearerAvailabilityNotifier( aServer ); + self->Construct(); + return self; + } + +// Destructor +CBearerAvailabilityNotifier::~CBearerAvailabilityNotifier() + { + Cancel(); + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CBearerAvailabilityNotifier::Receive +// Requests a new event (bearer (GPRS or WCDMA availability changed) from ETel +// ----------------------------------------------------------------------------- +// +void CBearerAvailabilityNotifier::Receive( TBool aKickOff ) + { + if ( IsActive() ) + { + return; + } + + if ( aKickOff ) + { + // Get current status of iPSD + TBool byCell( EFalse ); + + // Is GPRS or WCDMA supported + iServer->Iap()->GetBearerSupportInfo( + EBearerIdGPRS, + byCell, + iGPRSSupportedByPhone ); + + iServer->Iap()->GetBearerSupportInfo( + EBearerIdWCDMA, + byCell, + iWCDMASupportedByPhone ); + + if ( byCell && ( iGPRSSupportedByPhone || iWCDMASupportedByPhone ) ) + { + iPSD = ETrue; + } + } + + // Start receiving notifications if the phone supports some bearer + if ( iGPRSSupportedByPhone || iWCDMASupportedByPhone ) + { + iServer->Iap()->PacketService()->NotifyChangeOfNtwkRegStatus( + iStatus, + iRegStatus ); + SetActive(); + } + } + +// ----------------------------------------------------------------------------- +// CBearerAvailabilityNotifier::DoCancel +// Cancels the request from ETel. +// ----------------------------------------------------------------------------- +// +void CBearerAvailabilityNotifier::DoCancel() + { + if ( IsActive() ) + { + iServer->Iap()->PacketService()->CancelAsyncRequest( EPacketNotifyChangeOfNtwkRegStatus ); + } + } + +// ----------------------------------------------------------------------------- +// CBearerAvailabilityNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CBearerAvailabilityNotifier::RunL() + { + //LOGENTRFN("CBearerAvailabilityNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CBearerAvailabilityNotifier, status %d", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + LOGIT1("SERVER: Bearer availability event FAILED <%d>", iStatus.Int() ) + } + else + { + iEventInfo.Reset(); + + iEventInfo.iEventType = EConnMonBearerAvailabilityChange; + + if ( iGPRSSupportedByPhone || iWCDMASupportedByPhone ) + { + if ( iRegStatus != RPacketService::ENotRegisteredNotSearching && + iRegStatus != RPacketService::ENotRegisteredSearching && + iRegStatus != RPacketService::ERegistrationDenied && + iRegStatus != RPacketService::ENotRegisteredAndNotAvailable ) + { + // Check the capabilities of the cell + RPacketService::TDynamicCapsFlags capsDynamic; + TInt err = iServer->Iap()->PacketService()->GetDynamicCaps( capsDynamic ); + + if ( err != KErrNone ) + { + capsDynamic = 0; + } + + if ( ( capsDynamic & RPacketService::KCapsManualAttach ) || + ( capsDynamic & RPacketService::KCapsManualDetach ) ) + { + // Query the TSY for the attach mode + RPacketService::TAttachMode attachMode( RPacketService::EAttachWhenNeeded ); + err = iServer->Iap()->PacketService()->GetAttachMode( attachMode ); + + // Query packet network status (but only if the TSY is set to attach when possible) + if ( err == KErrNone && attachMode == RPacketService::EAttachWhenPossible ) + { + RPacketService::TStatus status( RPacketService::EStatusUnattached ); + err = iServer->Iap()->PacketService()->GetStatus( status ); + + if ( err == KErrNone && status != RPacketService::EStatusUnattached ) + { + iEventInfo.iData = ETrue; + } + } + else + { + // Attach mode is 'WhenNeeded' + iEventInfo.iData = ETrue; + } + } + } + + if ( static_cast< TUint >( iPSD ) != iEventInfo.iData ) + { + // Send BEARER availability changed -event. + // Find out the bearer ID (GPRS/WCDMA). + iServer->Iap()->GetBearerId( iEventInfo.iConnectionId ); + + // Send the event only if threshold is set by some of the clients. + TUint threshold( 0 ); + + iServer->CalculateThreshold( + EBearerIdAll, + EBearerAvailabilityThreshold, + threshold ); + + // Don't send the BEARER availability -event if nobody wants it (threshold = 0) + if ( threshold > 0 ) + { + iServer->EventQueue()->Add( iEventInfo ); + } + + LOGIT2("SERVER: EVENT -> Bearer availability changed: data %d, id %d", + iEventInfo.iData, iEventInfo.iConnectionId) + + iPSD = iEventInfo.iData; + } + } + + LOGIT("CBearerAvailabilityNotifier::RunL triggered HandleAvailabilityChange()") + iServer->AvailabilityManager()->HandleAvailabilityChange(); + + // This is due to off-line mode not triggering the event and user might + // think that the packet data is available still.. + iServer->Iap()->DtmStateChanged(); + } + // New request (with no initializations) + Receive( EFalse ); + //LOGEXITFN("CBearerAvailabilityNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CGsmSignalNotifier::CGsmSignalNotifier +// Notifies when GSM signal strength changes. +// ----------------------------------------------------------------------------- +// +CGsmSignalNotifier::CGsmSignalNotifier( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iMobilePhone( aMobilePhone ) + { + } + +// ----------------------------------------------------------------------------- +// CGsmSignalNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CGsmSignalNotifier::Construct() + { + //LOGENTRFN("CGsmSignalNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CGsmSignalNotifier") + //LOGEXITFN("CGsmSignalNotifier::Construct()") + } + +// ----------------------------------------------------------------------------- +// CGsmSignalNotifier::NewL +// ----------------------------------------------------------------------------- +// +CGsmSignalNotifier* CGsmSignalNotifier::NewL( + CConnMonServer* aServer, + RMobilePhone& aMobilePhone ) + { + CGsmSignalNotifier* self = new( ELeave ) CGsmSignalNotifier( aServer, aMobilePhone ); + self->Construct(); + return self; + } + +// Destructor +CGsmSignalNotifier::~CGsmSignalNotifier() + { + Cancel(); + + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CGsmSignalNotifier::Receive +// Requests a new event (signal strength changed) from ETel +// ----------------------------------------------------------------------------- +// +void CGsmSignalNotifier::Receive() + { + if ( IsActive() ) + { + return; + } + + TUint threshold( 0 ); + + // Threshold is owned by the session (not connection) + iServer->CalculateThreshold( EBearerIdAll, ESignalStrengthThreshold, threshold ); + + if ( threshold > 0 ) + { + iMobilePhone.NotifySignalStrengthChange( iStatus, iSignalStrength, iBar ); + SetActive(); + } + } + +// ----------------------------------------------------------------------------- +// CGsmSignalNotifier::DoCancel +// Cancels the request from ETel. +// ----------------------------------------------------------------------------- +// +void CGsmSignalNotifier::DoCancel() + { + if ( IsActive() ) + { + iMobilePhone.CancelAsyncRequest( EMobilePhoneNotifySignalStrengthChange ); + } + } + +// ----------------------------------------------------------------------------- +// CGsmSignalNotifier::RunL +// Handles the event that has arrived from ETel +// ----------------------------------------------------------------------------- +// +void CGsmSignalNotifier::RunL() + { + LOGENTRFN("CGsmSignalNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + if ( iStatus.Int() != KErrNone ) + { + LOGIT1("SERVER: GSM signal strength event FAILED <%d>", iStatus.Int() ) + } + else + { + // Is this a new registration status value + if ( iEventInfo.iData != static_cast< TUint >( iSignalStrength ) ) + { + iEventInfo.Reset(); + + iEventInfo.iData = iSignalStrength; + iEventInfo.iEventType = EConnMonSignalStrengthChange; + + // Find out bearer ID. + TInt err = iServer->Iap()->GetBearerId( iEventInfo.iConnectionId ); + + if ( err == KErrNone ) + { + iServer->EventQueue()->Add( iEventInfo ); + } + } + + LOGIT2("SERVER: EVENT -> Signal strength <%d>, id <%d>", iEventInfo.iData, iEventInfo.iConnectionId ) + + // New request + Receive(); + } + LOGEXITFN("CGsmSignalNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CActivityNotifier::CActivityNotifier +// ----------------------------------------------------------------------------- +// +CActivityNotifier::CActivityNotifier( + CConnMonServer* aServer, + RConnection* aConnection, + const TUint& aConnectionId, + const TUint& aSubConnectionId ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iConnection( aConnection ), + iConnectionId( aConnectionId), + iSubConnectionId( aSubConnectionId ), + iActivity( 0 ), + iPckgActivity( iActivity ) + { + } + +// ----------------------------------------------------------------------------- +// CActivityNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CActivityNotifier::Construct() + { + //LOGENTRFN("CActivityNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CActivityNotifier") + //LOGEXITFN("CActivityNotifier::Construct()") + } + +// Destructor +CActivityNotifier::~CActivityNotifier() + { + Cancel(); + + iServer = NULL; + iConnection = NULL; + } + +// ----------------------------------------------------------------------------- +// CActivityNotifier::Receive +// Requests a new event (activity changed) from RConnection +// ----------------------------------------------------------------------------- +// +void CActivityNotifier::Receive( TBool aActivity ) + { + if ( IsActive() ) + { + return; + } + + // Don't make a new request if previous + // status indicates that connection is closing + if ( iStatus == KErrDisconnected ) + { + return; + } + + iActivity = aActivity; + iServer->CalculateThreshold( iConnectionId, EActivityTimeThreshold, iThreshold ); + + if ( iThreshold > 0 ) + { + // Will complete when the connection activity has changed from given + // value (iActivity) for given period (threshold). + iConnection->IsConnectionActiveRequest( iThreshold, iPckgActivity, iStatus ); + SetActive(); + } + } + +// ----------------------------------------------------------------------------- +// CActivityNotifier::ReceiveOne +// Requests a new event (activity changed) from RConnection +// ----------------------------------------------------------------------------- +// +void CActivityNotifier::ReceiveOne( TBool aActivity ) + { + if ( IsActive() ) + { + Cancel(); + } + + iActivity = aActivity; + iThreshold = KOneTimeQueryThreshold; // 1 second + + // NOTE. Timer will expire once in a second. + // This should be used only with one shot querries ( -> cancel after a period + // if this has not completed otherwise ). + iConnection->IsConnectionActiveRequest( iThreshold, iPckgActivity, iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CActivityNotifier::DoCancel +// Cancels the request from RConnection. +// ----------------------------------------------------------------------------- +// +void CActivityNotifier::DoCancel() + { + if ( IsActive() ) + { + // Complete any outstanding one time queries if the are any + iServer->SendActivityToSessions( iConnectionId, iPckgActivity(), 0 ); + + LOGIT2("Activity completed (DoCancel): %d, id %d", iPckgActivity(), iConnectionId) + + // Cancel the request from RConnection + iConnection->IsConnectionActiveCancel(); + } + } + +// ----------------------------------------------------------------------------- +// CActivityNotifier::RunL +// Handles the event that has arrived from RConnection +// ----------------------------------------------------------------------------- +// +void CActivityNotifier::RunL() + { + //LOGENTRFN("CActivityNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CActivityNotifier, status %d", iStatus.Int()) + + if ( iThreshold == KOneTimeQueryThreshold ) + { + // One time query has been issued + iServer->SendActivityToSessions( iConnectionId, iPckgActivity(), iStatus.Int() ); + + LOGIT2("Activity req completed: %d, id %d", iPckgActivity(), iConnectionId) + + // Update internal table + iActivity = iPckgActivity(); + iServer->Iap()->UpdateActivity( iConnectionId, iActivity ); + + // Somebody has started notifications while we were waiting + // one time call to return -> go on with notifications + if ( ( iServer->NumberOfListeners() > 0 ) && ( iStatus.Int() == KErrNone ) ) + { + // Send event to clients + iEventInfo.Reset(); + + iEventInfo.iConnectionId = iConnectionId; + iEventInfo.iSubConnectionId = iSubConnectionId; + iEventInfo.iEventType = EConnMonConnectionActivityChange; + iEventInfo.iData = iPckgActivity(); + + iServer->EventQueue()->Add( iEventInfo ); + + Receive( iActivity ); + } + } + else + { + // A real event has been requested + if ( iStatus.Int() != KErrNone ) + { + if ( iStatus.Int() == KErrCancel ) + { + iStatus = KErrDisconnected; + } + + LOGIT2("Activity event FAILED <%d>, id %d", iStatus.Int(), iConnectionId) + } + else + { + iEventInfo.Reset(); + + // Send event(s) to clients + iEventInfo.iConnectionId = iConnectionId; + iEventInfo.iSubConnectionId = iSubConnectionId; + iEventInfo.iEventType = EConnMonConnectionActivityChange; + iEventInfo.iData = iPckgActivity(); + + LOGIT2("SERVER: EVENT -> Activity change: %d, id %d", iEventInfo.iData, iEventInfo.iConnectionId) + + iServer->EventQueue()->Add( iEventInfo ); + + // Update internal table + iActivity = iPckgActivity(); + iServer->Iap()->UpdateActivity( iConnectionId, iActivity ); + + // New request + Receive( iActivity ); + } + } + //LOGEXITFN("CActivityNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::CSubConnUpDownNotifier +// ----------------------------------------------------------------------------- +// +CSubConnUpDownNotifier::CSubConnUpDownNotifier( + CConnMonServer* aServer, + RConnection* aConnection, + const TUint& aConnectionId, + const TUint& aSubConnectionId ) + : + CActive( EConnMonPriorityMedium ), + iServer( aServer ), + iConnection( aConnection ), + iConnectionId( aConnectionId), + iSubConnectionId( aSubConnectionId ) + { + } + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::Construct +// ----------------------------------------------------------------------------- +// +void CSubConnUpDownNotifier::Construct() + { + //LOGENTRFN("CSubConnUpDownNotifier::Construct()") + CActiveScheduler::Add( this ); + LOGIT("Created CSubConnUpDownNotifier") + //LOGEXITFN("CSubConnUpDownNotifier::Construct()") + } + +// Destructor +CSubConnUpDownNotifier::~CSubConnUpDownNotifier() + { + if ( IsActive() ) + { + Cancel(); + } + + iServer = NULL; + iConnection = NULL; + } + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::Receive +// Requests a new event (subconnection up/down) from RConnection +// ----------------------------------------------------------------------------- +// +void CSubConnUpDownNotifier::Receive() + { + if ( IsActive() ) + { + Cancel(); + } + + if ( iStatus == KErrDisconnected ) + { + return; + } + + iConnection->AllSubConnectionNotification( iSubConnEventBuf, iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::SendDeletedEvent +// Sends connection deleted event to the clients +// ----------------------------------------------------------------------------- +// +void CSubConnUpDownNotifier::SendDeletedEvent() + { + if ( !iDeleteSent ) + { + iEventInfo.Reset(); + + iEventInfo.iEventType = EConnMonDeleteConnection; + iEventInfo.iConnectionId = iConnectionId; + iEventInfo.iSubConnectionId = iSubConnectionId; + iEventInfo.iData = iTotalDownlinkDataVolume; + iEventInfo.iData2 = iTotalUplinkDataVolume; + + // Find out type of the delete + CProgressNotifier* progressNotifier = 0; + TInt err = iServer->Iap()->GetProgressNotifier( iConnectionId, &progressNotifier ); + + if ( err == KErrNone ) + { + iEventInfo.iData3 = progressNotifier->IsAuthDelete(); + } + + // Send event to all clients that are listening + iServer->EventQueue()->Add( iEventInfo ); + + iDeleteSent = ETrue; + + if ( iInterfaceClosed ) + { + // Remove connection from the connection table if interface + // has closed. + TBearerInfo bearerInfo; + TConnInfo connInfo( 0, 0, iConnectionId, 0, bearerInfo ); + iServer->Iap()->RemoveConnection( connInfo ); + } + else + { + if ( progressNotifier->CanReconnect() ) + { + // Go on listening subinterface events + iConnection->AllSubConnectionNotification( iSubConnEventBuf, iStatus ); + SetActive(); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::DeleteSent +// ----------------------------------------------------------------------------- +// +TBool CSubConnUpDownNotifier::DeleteSent() const + { + return iDeleteSent; + } + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::SetInterfaceClosed +// ----------------------------------------------------------------------------- +// +void CSubConnUpDownNotifier::SetInterfaceClosed() + { + iInterfaceClosed = ETrue; + } + + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::DoCancel +// Cancels the request from RConnection. +// ----------------------------------------------------------------------------- +// +void CSubConnUpDownNotifier::DoCancel() + { + if ( IsActive() ) + { + iConnection->CancelAllSubConnectionNotification(); + } + } + +// ----------------------------------------------------------------------------- +// CSubConnUpDownNotifier::RunL +// Handles the event that has arrived from RConnection +// ----------------------------------------------------------------------------- +// +void CSubConnUpDownNotifier::RunL() + { + //LOGENTRFN("CSubConnUpDownNotifier::RunL()") + + // All RunL():s outside CServer-derived main class MUST NOT LEAVE. + // Use TRAPD when needed. + + LOGIT(".") + LOGIT1("RunL: CSubConnUpDownNotifier, status %d", iStatus.Int()) + + if ( iStatus.Int() != KErrNone ) + { + LOGIT2("SERVER: subconn up/down event for id %d FAILED <%d>", iConnectionId, iStatus.Int()) + + if ( iStatus.Int() == KErrNotReady ) + { + // Subinterface has disappered + CProgressNotifier* progressNotifier = 0; + TInt err = iServer->Iap()->GetProgressNotifier( iConnectionId, &progressNotifier ); + if ( err == KErrNone ) + { + // Is progress notifier still alive + if ( !progressNotifier->IsActive() ) + { + SendDeletedEvent(); + } + } + } + + iStatus = KErrDied; + } + else + { + TSubConnectionEvent& event = ( TSubConnectionEvent& )( *iSubConnEventBuf.Ptr() ); + + if ( event.iSubConnectionUniqueId == 0 && event.iEventType == ESubConnectionClosed ) + { + TSubConnectionClosedEvent& closedEvent = + (TSubConnectionClosedEvent&)( *iSubConnEventBuf.Ptr() ); + iTotalDownlinkDataVolume = closedEvent.iTotalDownlinkDataVolume; + iTotalUplinkDataVolume = closedEvent.iTotalUplinkDataVolume; + + LOGIT3("SERVER: EVENT -> Connection %d closed, u: %d, d: %d", + iConnectionId, iTotalUplinkDataVolume, iTotalDownlinkDataVolume) + + CProgressNotifier* progressNotifier = 0; + TInt err = iServer->Iap()->GetProgressNotifier( iConnectionId, &progressNotifier ); + if ( err == KErrNone ) + { + // Progess notifier has stopped and allinterface closed event has arrived + if ( !progressNotifier->IsActive() ) + { + SendDeletedEvent(); + } + } + else + { + SendDeletedEvent(); + } + + iStatus = KErrDisconnected; + } + else if ( ( event.iSubConnectionUniqueId == 0 ) && + ( event.iEventType == ESubConnectionOpened ) ) + { + // IS THIS A RECONNECT + if ( iDeleteSent && !iInterfaceClosed ) + { + TUint newId( iConnectionId ); + TInt err = iServer->Iap()->Reconnect( newId ); + + if ( err == KErrNone ) + { + iEventInfo.Reset(); + iEventInfo.iEventType = EConnMonCreateConnection; + iEventInfo.iConnectionId = newId; + + // Send event to all clients that are listening + iServer->EventQueue()->Add( iEventInfo ); + + LOGIT1("SERVER: EVENT -> new connection %d created (RECONNECTED)", newId) + delete this; + } + } + else + { + // New request + Receive(); + } + } + else + { + // New request + iConnection->AllSubConnectionNotification( iSubConnEventBuf, iStatus ); + SetActive(); + } + } + //LOGEXITFN("CSubConnUpDownNotifier::RunL()") + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CTimerAO::CTimerAO +// ----------------------------------------------------------------------------- +// +CTimerAO::CTimerAO( + CConnMonServer* aServer, + const TUint& aConnectionId, + const TUint8& aActivity ) + : + CActive( EConnMonPriorityNormal ), + iServer( aServer ), + iConnectionId( aConnectionId ), + iActivity( aActivity ) + { + } + +// ----------------------------------------------------------------------------- +// CTimerAO::ConstructL +// ----------------------------------------------------------------------------- +// +void CTimerAO::ConstructL() + { + //LOGENTRFN("CTimerAO::ConstructL()") + CActiveScheduler::Add( this ); + User::LeaveIfError( iTimer.CreateLocal() ); + //LOGEXITFN("CTimerAO::ConstructL()") + } + +// Destructor +CTimerAO::~CTimerAO() + { + Cancel(); + iTimer.Close(); + + iServer = NULL; + } + +// ----------------------------------------------------------------------------- +// CTimerAO::Start +// ----------------------------------------------------------------------------- +// +void CTimerAO::Start() + { + if ( !IsActive() ) + { + iTimer.After( iStatus, KActivityTimeout ); + SetActive(); + } + } + +// ----------------------------------------------------------------------------- +// CTimerAO::DoCancel +// ----------------------------------------------------------------------------- +// +void CTimerAO::DoCancel() + { + if ( IsActive() ) + { + iTimer.Cancel(); + } + } + +// ----------------------------------------------------------------------------- +// CTimerAO::RunL +// ----------------------------------------------------------------------------- +// +void CTimerAO::RunL() + { + CActivityNotifier* activityNotifier = 0; + + TInt err = iServer->Iap()->GetActivityNotifier( iConnectionId, &activityNotifier ); + + if ( ( err == KErrNone ) && ( activityNotifier != 0 ) ) + { + if ( activityNotifier->IsActive() ) + { + TUint threshold( activityNotifier->Threshold() ); + + if ( threshold == KOneTimeQueryThreshold ) + { + // Timer has completed before one time activity query. + // Cancel it to complete client requests + activityNotifier->Cancel(); + + // Someboby has started notifications while we were waiting this to + // complete -> go on with the notifications + if ( iServer->NumberOfListeners() > 0 ) + { + activityNotifier->Receive( iActivity ); + } + } + } + } + + delete this; + } + +// End-of-file