--- /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 <es_enum_partner.h>
+#endif
+#include <e32base.h>
+#include <rmmcustomapi.h>
+#include <featmgr.h>
+
+#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