diff -r 000000000000 -r 5a93021fdf25 connectionmonitoring/connmon/connectionmonitor/src/ConnMonIAP.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectionmonitoring/connmon/connectionmonitor/src/ConnMonIAP.cpp Thu Dec 17 08:55:21 2009 +0200 @@ -0,0 +1,5031 @@ +/* +* Copyright (c) 2002-2009 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: Core functionality for ConnMon. +* +*/ + +#include +#include +#include +#include +#include + +#include "ConnMonServ.h" +#include "ConnMonSess.h" +#include "CEventQueue.h" +#include "CCsdFax.h" +#include "CPsdFax.h" +#include "ConnMonIAP.h" +#include "ConnMonNoti.h" +#include "CDataVolume.h" +#include "connmondtmnoti.h" +#include "connmontelnoti.h" +#include "ConnMonBearerNotifier.h" +#include "log.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// TConnInfo::TConnInfo +// ----------------------------------------------------------------------------- +// +TConnInfo::TConnInfo( + TInt aIapId, + TInt aNetId, + TUint aConnectionId, + TInt aBearer, + TBearerInfo aBearerInfo ) + : + iIapId( aIapId ), + iNetId( aNetId ), + iConnectionId( aConnectionId ), + iBearer( aBearer ), + iConnAttach( 0 ), + iProgressNotifier( 0 ), + iDLDataNotifier( 0 ), + iULDataNotifier( 0 ), + iDataVolumeAO( 0 ), + iConnDownNotifier( 0 ), + iActivityNotifier( 0 ), + iActivity( 0 ), + iBearerInfo( aBearerInfo ), + iBearerNotifier( 0 ) + { + } + +// ----------------------------------------------------------------------------- +// TConnInfo::Reset +// ----------------------------------------------------------------------------- +// +void TConnInfo::Reset() + { + // Only call this function to initialize a newly created TConnInfo-object. + // (There is no cleanup) + iIapId = 0; + iNetId = 0; + iConnectionId = 0; + iBearer = EBearerUnknown; + iBearerInfo.iBearer = EBearerInfoUnknown; + iBearerInfo.iInternal = ETrue; + iProgressNotifier = 0; + iDLDataNotifier = 0; + iULDataNotifier = 0; + iDataVolumeAO = 0; + iConnAttach = 0; + iConnDownNotifier = 0; + iActivityNotifier = 0; + iActivity = 0; + iBearerNotifier = 0; + } + +// ----------------------------------------------------------------------------- +// TConnInfo::Compare +// Compares two TConnInfo items (by connection id). +// ----------------------------------------------------------------------------- +// +TInt TConnInfo::Compare( const TConnInfo& aFirst, const TConnInfo& aSecond ) + { + if ( aFirst.iConnectionId < aSecond.iConnectionId ) + { + return -1; + } + + if ( aFirst.iConnectionId > aSecond.iConnectionId ) + { + return 1; + } + return 0; + } + +// ----------------------------------------------------------------------------- +// TConnInfo::MatchId +// Finds TConnInfo item matching by connection Id. +// ----------------------------------------------------------------------------- +// +TBool TConnInfo::MatchId( const TConnInfo& aFirst, const TConnInfo& aSecond ) + { + if ( aFirst.iConnectionId == aSecond.iConnectionId ) + { + return ETrue; + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// TConnInfo::MatchIap +// Finds TConnInfo item matching by iap id and net id. +// ----------------------------------------------------------------------------- +// +TBool TConnInfo::MatchIap( const TConnInfo& aFirst, const TConnInfo& aSecond ) + { + // Only internal bearers can be matched by IapId and NetId + if ( ( aFirst.iIapId == aSecond.iIapId ) && ( aFirst.iNetId == aSecond.iNetId ) && + ( aFirst.iBearer < EBearerExternalCSD ) && ( aSecond.iBearer < EBearerExternalCSD ) && + ( aFirst.iBearerInfo.iInternal ) && ( aSecond.iBearerInfo.iInternal ) ) + { + return ETrue; + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// TConnInfo::MatchBearer +// Finds TConnInfo item matching by bearer. +// ----------------------------------------------------------------------------- +// +TBool TConnInfo::MatchBearer( const TConnInfo& aFirst, const TConnInfo& aSecond ) + { + // External CSD bearers (there is no event availabe for bearer change) + if ( ( aFirst.iBearer == EBearerExternalCSD || aFirst.iBearer == EBearerExternalHSCSD || + aFirst.iBearer == EBearerExternalWcdmaCSD ) + && + ( aSecond.iBearer == EBearerExternalCSD || aSecond.iBearer == EBearerExternalHSCSD || + aSecond.iBearer == EBearerExternalWcdmaCSD ) ) + { + return ETrue; + } + + // External PSD bearers (there is not always an event availabe for bearer change) + else if ( ( aFirst.iBearer == EBearerExternalGPRS || + aFirst.iBearer == EBearerExternalEdgeGPRS || + aFirst.iBearer == EBearerExternalWCDMA || + aFirst.iBearer == EBearerExternalCDMA2000 || + ( !aFirst.iBearerInfo.iInternal && + ( aFirst.iBearerInfo.iBearer == EBearerInfoHSDPA || + aFirst.iBearerInfo.iBearer == EBearerInfoHSUPA || + aFirst.iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) + && + ( aSecond.iBearer == EBearerExternalGPRS || + aSecond.iBearer == EBearerExternalEdgeGPRS || + aSecond.iBearer == EBearerExternalWCDMA || + aSecond.iBearer == EBearerExternalCDMA2000 || + ( !aSecond.iBearerInfo.iInternal && + ( aSecond.iBearerInfo.iBearer == EBearerInfoHSDPA || + aSecond.iBearerInfo.iBearer == EBearerInfoHSUPA || + aSecond.iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) ) + + { + return ETrue; + } + + // Other bearers + else if ( aFirst.iBearer == aSecond.iBearer && + aFirst.iBearerInfo.iBearer == aSecond.iBearerInfo.iBearer ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CConnMonIAP::CConnMonIAP +// ----------------------------------------------------------------------------- +// +CConnMonIAP::CConnMonIAP( CConnMonServer* aServer ) + : + iServer( aServer ), + iEndUserNetIds( KNullDesC8 ) + { + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::ConstructL +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::ConstructL() + { + LOGENTRFN("CConnMonIAP::ConstructL()") + TInt err( KErrNone ); + + // Connect to socket server and use system global pool (-1) for message slots. + User::LeaveIfError( iSocketServer.Connect( static_cast( -1 ) ) ); + LOGIT("(01/11) Loaded OK: ESock") + + // Open RConnection. This object is not attached to any connection + User::LeaveIfError( iConnection.Open( iSocketServer ) ); + LOGIT("(02/11) Opened OK: RConnection") + + // Connect to ETel server + TBuf tsyName; + tsyName.Copy( KMmTsyModuleName ); + + // The RTelServer::Connect() might not always work with the first trial, + // because of a coding error related to using semaphores in the method. + for ( TInt a = 0; a < KPhoneRetryCount; a++ ) + { + err = iTelServer.Connect(); + if ( KErrNone == err ) + { + break; + } + User::After( KPhoneRetryTimeout ); + LOGIT("RTelServer::Connect() failed, trying again.") + } + User::LeaveIfError( err ); + LOGIT("(03/11) Loaded OK: ETel") + + // Initialize FeatureManager + FeatureManager::InitializeLibL(); + LOGIT("(04/11) Loaded OK: FeatureManager") + + // Try to load tsy + err = iTelServer.LoadPhoneModule( tsyName ); + if ( KErrNone == err ) + { + LOGIT("(05/11) Loaded OK: TSY") + iTSYLoaded = 1; + + // Phone info can be retrieved with value 0 if there is only one phone + RTelServer::TPhoneInfo info; + User::LeaveIfError( iTelServer.GetPhoneInfo( 0, info ) ); + LOGIT("(06/11) Loaded OK: Phone info") + + User::LeaveIfError( iMobilePhone.Open( iTelServer, info.iName ) ); + LOGIT("(07/11) Opened OK: RMobilePhone") + + // Open packet service + err = iPacketService.Open( iMobilePhone ); + if ( KErrNone == err ) + { + LOGIT("(08/11) Loaded OK: Packet service") + iPacketServLoaded = 1; + + // CDMA network does not support external connections. PSD Fax handler module + // should not be created when in CDMA network. The code below works OK as long + // as there is no phone that supports both CDMA and GSM at the same time. + if ( !FeatureManager::FeatureSupported( KFeatureIdProtocolCdma ) ) + { + // Create PSD Fax handler module + iPsdFax = new( ELeave ) CPsdFax( + iServer, + &iTelServer, + &iMobilePhone, + &iPacketService ); + iPsdFax->ConstructL(); + LOGIT("(09/11) Loaded OK: PSD module") + } + else + { + LOGIT("(09/11) Nosupport: PSD module not loaded, no PSD support in CDMA networks.") + } + } + else + { + LOGIT1("(08/11) Loaderror: Packet service failed with code <%d>", err) + } + + // CDMA network does not support external connections. CSD Fax handler module + // should not be created when in CDMA network. The code below works OK as long + // as there is no phone that supports both CDMA and GSM at the same time. + if ( !FeatureManager::FeatureSupported( KFeatureIdProtocolCdma ) ) + { + // Create CSD Fax handler module + iCsdFax = new( ELeave ) CCsdFax( iServer, &iTelServer, &iMobilePhone ); + iCsdFax->ConstructL(); + LOGIT("(10/11) Loaded OK: CSD module") + } + else + { + LOGIT("(10/11) Nosupport: CSD module not loaded, no CSD support in CDMA networks") + } + } + else + { + LOGIT1("(05/11) Loaderror: TSY failed with code <%d>", err) + } + + // Open WLAN Management service + if ( FeatureManager::FeatureSupported( KFeatureIdProtocolWlan ) ) + { + TRAPD( leaveCode, iWlanSupport = CWlanSupport::NewL( iServer ) ); + if ( KErrNone != leaveCode ) + { + LOGIT1("(11/11) Loaderror: WLAN module failed with code <%d>", leaveCode) + } + else + { + LOGIT("(11/11) Loaded OK: WLAN module") + } + } + else + { + LOGIT("(11/11) Nosupport: WLAN module not loaded, no WLAN support detected") + } + + LOGEXITFN("CConnMonIAP::ConstructL()") + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::~CConnMonIAP +// ----------------------------------------------------------------------------- +// +// Destructor +CConnMonIAP::~CConnMonIAP() + { + LOGENTRFN("CConnMonIAP::~CConnMonIAP()") + // Delele dial up modules. + delete iCsdFax; + iCsdFax = NULL; + + delete iPsdFax; + iPsdFax = NULL; + + // Delete global notifications. This must be called before + // services are closed or destroyed below. + DeleteNotifications(); + + // Delete connection up/down notification. + if ( iConnUpDownNotifier != 0 ) + { + iConnUpDownNotifier->Cancel(); + delete iConnUpDownNotifier; + } + + // Close all attached connections + TInt count = iConnInfos.Count(); + + for ( TInt i = 0; i < count; i++ ) + { + if ( iConnInfos[i].iConnAttach != 0 ) + { + iConnInfos[i].iConnAttach->Close(); + delete iConnInfos[i].iConnAttach; + } + } + + // Note. all sessions have closed by now. + // There is no need to delete connection parameters + // because session destructors have already done that. + iConnInfos.Close(); + + // Close "global" ESOCK objects + iConnection.Close(); + iSocketServer.Close(); + + // Close "global" ETEL objects + if ( iPacketServLoaded == 1 ) + { + iPacketService.Close(); + } + + iMobilePhone.Close(); + iTelServer.Close(); + + // Unload FeatureManager + FeatureManager::UnInitializeLib(); + + // Destroy WLAN service + delete iWlanSupport; + iWlanSupport = NULL; + + // Reset global pointers + iServer = NULL; + iPsdNetwStatusNotifier = NULL; + iNetwRegistrationNotifier = NULL; + iEdgeNotifier = NULL; + iWcdmaNotifier = NULL; + iModeNotifier = NULL; + iGSMSignalNotifier = NULL; + iGSMBearerAvailabilityNotifier = NULL; + + // Clean up all ECom sessions + // More info about it: TSW EGUO-64LD36 + REComSession::FinalClose(); + LOGEXITFN("CConnMonIAP::~CConnMonIAP()") + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::EnumerateConnections +// Enumerates active connections using RConnection API. +// Refreshes iConnInfos array (server view) with the latest information. +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::EnumerateConnections( TUint& aCount ) + { + // Server must be 'blocked' while updating the connection table. + TConnectionInfoBuf connInfoBuf; + TBearerInfo bearerInfo; + TConnInfo connInfo( 0, 0, 0, 0, bearerInfo ); + TInt err( KErrNone ); + + aCount = 0; + RArray tempArray; + + // Get existing external (fax) CSD connections + // These can't be enumerated from ETEL at the moment + if ( iCsdFax ) + { + // In practise there can be only ONE fax connection of this type + connInfo.Reset(); + connInfo.iBearer = EBearerExternalCSD; // This will match any ext-CSD + connInfo.iBearerInfo.iBearer = EBearerInfoCSD; + connInfo.iBearerInfo.iInternal = EFalse; + + TInt index = iConnInfos.Find( connInfo, TConnInfo::MatchBearer ); + if ( ( KErrNotFound != index ) && iCsdFax->IsValid() ) + { + // Add to temp array + tempArray.Append( iConnInfos[index] ); + aCount++; + } + else if ( !iConnUpDownNotifier ) + { + // Try to find out about external CSD connections + // that were alive before CM server started. + // The code below will be executed only when + // this method is called for the first time. + err = iCsdFax->FindCall(); + if ( KErrNone == err ) + { + iCsdFax->GetBearer( connInfo.iBearer, connInfo.iBearerInfo ); + connInfo.iConnectionId = NewConnectionId(); // New unique Id + iCsdFax->SetConnectionId( connInfo.iConnectionId ); + tempArray.Append( connInfo ); + aCount++; + } + } + } + + // Get existing external (fax) PSD connections + // These connections can't be enumerated from ETEL at the moment + // Only notification of a new connection is available from ETEL. + if ( iPsdFax ) + { + connInfo.Reset(); + connInfo.iBearer = EBearerExternalGPRS; // This will match any ext-PSD + connInfo.iBearerInfo.iBearer = EBearerInfoGPRS; + connInfo.iBearerInfo.iInternal = EFalse; + + // Check all external PSD connections + for ( TUint index = 0; index < iConnInfos.Count(); index++ ) + { + // Check that connection bearer is external PSD + if ( iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCDMA2000 || + ( !iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) + { + // Check if connection is still valid + if ( iPsdFax->IsValid( iConnInfos[index].iConnectionId ) ) + { + // Add to temp array + tempArray.Append( iConnInfos[index] ); + aCount++; + } + } + } + + if ( !iConnUpDownNotifier ) + { + for( TUint index = 0; index < KMaxPsdConnectionCount; index++ ) + { + // Try to find out about external PSD connections + // that were alive before CM server started. + // The code below will be executed only when + // this method is called for the first time. + TBuf tempName( KExternalName ); + + // Add connection number to string if index is > 1 + if ( index > 0 ) + { + tempName.AppendNum( index+1 ); + } + + // Try to open connection context + err = iPsdFax->OpenContext( index, tempName ); + if ( KErrNone == err ) + { + iPsdFax->GetBearer( connInfo.iBearer, connInfo.iBearerInfo ); + connInfo.iConnectionId = NewConnectionId(); // New unique Id + err = iPsdFax->SetConnectionId( index, connInfo.iConnectionId ); + if ( KErrNone == err ) + { + tempArray.Append( connInfo ); + aCount++; + } + } + } + } + } + + const TUint initialCount = iConnInfos.Count(); + __ASSERT_DEBUG( ( aCount == static_cast( tempArray.Count() ) ), + PanicServer( EIapArrayError ) ); + + TUint k( 0 ); + // Remove resources owned by obsolete connections + for ( k = 0; k < initialCount; k++ ) + { + TInt index( KErrNotFound ); + + if ( iConnInfos[k].iBearer < EBearerExternalCSD ) + { + index = tempArray.Find( iConnInfos[k], TConnInfo::MatchIap ); // Internal + } + else + { + index = tempArray.Find( iConnInfos[k], TConnInfo::MatchBearer ); // External + } + + if ( KErrNotFound == index ) + { + TBool deleteSent( ETrue ); + + if ( iConnInfos[k].iConnDownNotifier != 0 ) + { + deleteSent = iConnInfos[k].iConnDownNotifier->DeleteSent(); + } + + TInt connStatus( 0 ); + TInt ret = GetConnectionStatus( k, connStatus ); + + if ( ( ( KErrNone != ret ) || ( connStatus == 0 ) ) && deleteSent ) + { + LOGIT3("Removing old connection, index %d, id %d, bearer %d", + k, iConnInfos[k].iConnectionId, iConnInfos[k].iBearer) + iServer->RemoveConnSettingsFromSessions( iConnInfos[k].iConnectionId ); + DeleteConnNotifications( k ); + + // Close attached connection + if ( iConnInfos[k].iConnAttach != 0 ) + { + iConnInfos[k].iConnAttach->Close(); + delete iConnInfos[k].iConnAttach; + } + } + else + { + // Add connection to temp array because connection status is valid. + tempArray.Append( iConnInfos[k] ); + aCount++; + } + } + } + + // Replace old iConnInfos array with tempArray + // Reserve enough room + for ( TUint i = initialCount; i < aCount; i++ ) + { + TInt error = iConnInfos.Append( tempArray[0] ); + if ( error ) + { + // Rollback reserved entries + for ( TUint j = i; j > initialCount; j-- ) + { + iConnInfos.Remove( j-1 ); + } + tempArray.Reset(); + tempArray.Close(); + return error; + } + } + + // Safe from leaves from here. Copy over new contents + iConnInfos.Reset(); + for ( k = 0; k < aCount; k++ ) + { + iConnInfos.Append( tempArray[k] ); + } + + // Print connection info array to log + #ifdef _DEBUG + LOGIT("EnumerateConnections: Connection info array:") + for ( TInt m = 0; m < iConnInfos.Count(); m++ ) + { + LOGIT4(" id %d, bearer %d, iapId %d, netId %d", iConnInfos[m].iConnectionId, + iConnInfos[m].iBearer, iConnInfos[m].iIapId, iConnInfos[m].iNetId) + } + #endif // _DEBUG + + tempArray.Reset(); + tempArray.Close(); + + err = KErrNone; + // Start connection up/down notifier if not already running + if ( !iConnUpDownNotifier ) + { + // Leave left out intentionally, check for NULL instead + iConnUpDownNotifier = new CConnUpDownNotifier( iServer ); // No (ELeave) + if ( !iConnUpDownNotifier ) + { + err = KErrNoMemory; + } + else + { + iConnUpDownNotifier->Construct(); + } + } + if ( KErrNone == err ) + { + if ( !iConnUpDownNotifier->IsActive() ) + { + iConnUpDownNotifier->Receive(); // (re)start listening + } + // Add event watchers for the new connections. Old connections already have + // notifications on and AddConnNotificationsL() will only restart the event + // watchers if they have stopped (because of an error situation). + if ( iCountListeners > 0 ) + { + TRAP( err, + { + for ( k = 0; k < aCount; k++ ) + { + AddConnNotificationsL( k ); + } + } ); + } + } + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::EnumerateConnectionsL +// Enumerates active connections using RConnection API. +// Refreshes iConnInfos array (server view) with the latest information. +// Fills aEnumInfo array (client view) with the newly enumerated connection ids. +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::EnumerateConnectionsL( TUint& aCount, CArrayFixFlat& aEnumInfo ) + { + LOGENTRFN("CConnMonIAP::EnumerateConnectionsL()") + TInt err( KErrNone ); + + err = EnumerateConnections( aCount ); + if ( KErrNone == err ) + { + // Fill in table (connection ids) owned by the session + // Client needs this table when querying connection info index by index. + aEnumInfo.Reset(); + + if ( aCount > 0 ) + { + for ( TUint k = 0; k < aCount; k++ ) + { + // Sometimes there is a delay after the DELETE event has arrived and + // before the closed connection is removed from Esock. Hide these closing + // connections from clients. + TBool deleteSent( EFalse ); + + if ( iConnInfos[k].iConnDownNotifier != 0 ) + { + deleteSent = iConnInfos[k].iConnDownNotifier->DeleteSent(); + } + + if ( !deleteSent ) + { + aEnumInfo.AppendL( iConnInfos[k].iConnectionId ); + } + } + aCount = aEnumInfo.Count(); + } + } + + LOGEXITFN1("CConnMonIAP::EnumerateConnectionsL()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::ConnectionExists +// Checks if given connection id is valid +// ----------------------------------------------------------------------------- +// +TBool CConnMonIAP::ConnectionExists( const TUint& aConnectionId ) + { + LOGENTRFN("CConnMonIAP::ConnectionExists()") + TBool res( EFalse ); + + if ( aConnectionId == 0 || aConnectionId >= KMaxConnectionId ) + { + res = EFalse; + } + else + { + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + res = EFalse; + } + else + { + res = ETrue; + } + } + + LOGEXITFN1("CConnMonIAP::ConnectionExists()", res) + return res; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetConnectionInfo +// Returns the number of subconnections in aSubConnectionCount +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetConnectionInfo( + const TUint& aConnectionId, + TUint& aSubConnectionCount ) + { + LOGENTRFN("CConnMonIAP::GetConnectionInfo()") + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + err = KErrNotFound; + } + else + { + // Get the number of subconnections + if ( iConnInfos[index].iBearer < EBearerExternalCSD ) + { + // Internal connections + aSubConnectionCount = 1; + err = iConnInfos[index].iConnAttach->EnumerateSubConnections( + aSubConnectionCount ); + if ( KErrNotReady == err ) + { + err = KErrNone; + } + } + else + { + // External connections + aSubConnectionCount = 1; + } + } + + LOGEXITFN1("CConnMonIAP::GetConnectionInfo()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetIntAttributeL +// Returns the integer attribute in aValue +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetIntAttributeL( const RMessage2& aMessage, TInt& aValue ) + { + LOGENTRFN("CConnMonIAP::GetIntAttributeL()") + TInt ret( KErrNone ); + TUint connectionId( aMessage.Int0() ); + TUint attribute( aMessage.Int2() ); + + LOGIT2("SERVER: CConnMonIAP::GetIntAttributeL(): connId %d, attribute %d", connectionId, attribute) + + if ( KBearerInfo == attribute ) + { + LOGIT("SERVER: CConnMonIAP::GetIntAttributeL(): KBearerInfo") + TBearerInfo bearerInfo; + ret = GetBearerInfo( connectionId, bearerInfo ); + if ( KErrNone == ret ) + { + aValue = bearerInfo.iBearer; + } + return ret; + } + + if ( KWlanScanCacheLifetime == attribute ) + { + // Check WLAN support for the given id + ret = WlanSupportCheck( connectionId ); + if ( KErrNone == ret ) + { + ret = iWlanSupport->GetIntAttributeL( aMessage, aValue ); + } + return ret; + } + + // Handle requests that use a bearer specific connection IDs + if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA ) && + ( attribute == KNetworkStatus ) ) + { + return ( GetPsdNetworkStatus( aValue ) ); + } + else if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA || + connectionId == EBearerIdCSD || connectionId == EBearerIdGSM || + connectionId == EBearerIdWcdmaCSD ) + && ( attribute == KNetworkRegistration ) ) + { + return ( GetNetworkRegistration( aValue ) ); + } + else if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA || + connectionId == EBearerIdCSD || connectionId == EBearerIdGSM || + connectionId == EBearerIdWcdmaCSD ) + && ( attribute == KNetworkRegistration_v2 ) ) + { + return ( GetNetworkRegistration_v2( aValue ) ); + } + else if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA || + connectionId == EBearerIdCSD || connectionId == EBearerIdGSM || + connectionId == EBearerIdWcdmaCSD ) + && ( attribute == KSignalStrength ) ) + { + return ( GetGSMSignalStrength( aValue ) ); + } + else if ( connectionId == EBearerIdWLAN && attribute == KSignalStrength ) + { + if ( iWlanSupport ) + { + ret = iWlanSupport->GetSignalStrengthL( aMessage, aValue ); + } + else + { + ret = KErrNotSupported; + } + return ret; + } + else if ( ( connectionId == EBearerIdGPRS ) && ( attribute == KBearer ) ) + { + // Check which is the bearer of the GPRS cell. + if ( IsEdgeCell() ) + { + aValue = EBearerEdgeGPRS; + } + else + { + aValue = EBearerGPRS; + } + return KErrNone; + } + + // Find connection matching the given Id + TInt index = Index( connectionId ); + if ( index < 0 ) + { + return KErrNotFound; + } + + LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): index %d", index) + + // Find out bearer if not already set. + if ( iConnInfos[index].iBearer == EBearerUnknown ) + { + ret = GetBearer( + connectionId, + iConnInfos[index].iBearer, + iConnInfos[index].iBearerInfo ); + + if ( ret != KErrNone ) + { + LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): Error getting bearer info for connection <%d>", ret) + return ret; + } + LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): bearer was unknown, now %d", iConnInfos[index].iBearer) + } + + switch ( attribute ) + { + case KBearer: + { + // BEARER + LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): case KBearer, bearer %d", iConnInfos[index].iBearer) + // Bearer is never unknown for the external connections + // but sometimes it is not valid (e.g. CSD/HSCSD) until + // connection reaches certain status. + if ( ( iConnInfos[index].iBearer == EBearerExternalCSD ) || + ( iConnInfos[index].iBearer == EBearerExternalHSCSD ) || + ( iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) ) + { + if ( iCsdFax ) + { + iCsdFax->GetBearer( iConnInfos[index].iBearer, iConnInfos[index].iBearerInfo ); + } + } + else if ( ( iConnInfos[index].iBearer == EBearerExternalGPRS ) || + ( iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ) || + ( iConnInfos[index].iBearer == EBearerExternalWCDMA ) ) + { + if ( iPsdFax ) + { + iPsdFax->GetBearer( iConnInfos[index].iBearer, iConnInfos[index].iBearerInfo ); + } + } + else if ( iConnInfos[index].iBearer < EBearerExternalCSD ) + { + // CSD/HSCSD info could change after the first query + // also GPRS/EdgeGPRS/WCDMA info can change + TInt bearer( EBearerUnknown ); + TBearerInfo bearerInfo; + + ret = GetBearer( connectionId, bearer, bearerInfo ); + if ( iConnInfos[index].iBearer != bearer ) + { + LOGIT4("Bearer changed: id %d, iapId %d, old bearer %d, new bearer %d", + iConnInfos[index].iConnectionId, iConnInfos[index].iIapId, + iConnInfos[index].iBearer, bearer) + } + + if ( ( bearer != EBearerUnknown && bearerInfo.iBearer != EBearerInfoUnknown ) + && ( ret == KErrNone ) ) + { + iConnInfos[index].iBearer = bearer; + iConnInfos[index].iBearerInfo = bearerInfo; + } + } + aValue = iConnInfos[index].iBearer; + } + break; + + case KNetworkStatus: + { + // NETWORK STATUS + if ( iConnInfos[index].iBearer == EBearerGPRS || + iConnInfos[index].iBearer == EBearerEdgeGPRS || + iConnInfos[index].iBearer == EBearerWCDMA || + iConnInfos[index].iBearer == EBearerCDMA2000 || + iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCDMA2000 ) + { + // psd + ret = GetPsdNetworkStatus( aValue ); + } + else if ( iConnInfos[index].iBearer == EBearerUnknown ) + { + // GetBearer() : iMobilePhone.GetCurrentMode() + // is not always working for PSD when starting the first + // connection. So this must be some PSD... + ret = GetPsdNetworkStatus( aValue ); + } + else + { + // Others not supported at the moment + aValue = EConnMonStatusNotAvailable; + ret = KErrNone; + } + } + break; + + case KConnectionStatus: + { + // CONNECTION STATUS + if ( iConnInfos[index].iBearer < EBearerExternalCSD ) + { + // Internal connections + ret = GetConnectionStatus( index, aValue ); + } + else if ( iConnInfos[index].iBearer == EBearerExternalCSD || + iConnInfos[index].iBearer == EBearerExternalHSCSD || + iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) + { + // External csd + if ( iCsdFax ) + { + ret = iCsdFax->GetStatus( aValue ); + } + else + { + ret = KErrNotFound; + } + } + else + { + // External psd + if ( iPsdFax ) + { + ret = iPsdFax->GetStatus( connectionId, aValue ); + } + else + { + ret = KErrNotFound; + } + } + } + break; + + case KProtocolType: + { + // PROTOCOL TYPE + if ( iConnInfos[index].iBearer == EBearerGPRS || + iConnInfos[index].iBearer == EBearerEdgeGPRS || + iConnInfos[index].iBearer == EBearerWCDMA ) + { + ret = GetProtocolTypeL( connectionId, aValue ); + } + else if ( iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA ) + { + if ( iPsdFax ) + { + ret = iPsdFax->GetProtocolType( connectionId, aValue ); + } + else + { + ret = KErrNotFound; + } + } + else + { + aValue = EProtocolTypeUnknown; + } + } + break; + + case KNetworkRegistration: + { + // NETWORK REGISTRATION STATUS + if ( iConnInfos[index].iBearer == EBearerGPRS || + iConnInfos[index].iBearer == EBearerEdgeGPRS || + iConnInfos[index].iBearer == EBearerWCDMA || + iConnInfos[index].iBearer == EBearerCSD || + iConnInfos[index].iBearer == EBearerHSCSD || + iConnInfos[index].iBearer == EBearerWcdmaCSD || + iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCSD || + iConnInfos[index].iBearer == EBearerExternalHSCSD || + iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) + { + ret = GetNetworkRegistration( aValue ); + } + else + { + aValue = ENetworkRegistrationNotAvailable; + ret = KErrNone; + } + } + break; + case KNetworkRegistration_v2: + { + // NETWORK REGISTRATION STATUS + if ( iConnInfos[index].iBearer == EBearerGPRS || + iConnInfos[index].iBearer == EBearerEdgeGPRS || + iConnInfos[index].iBearer == EBearerWCDMA || + iConnInfos[index].iBearer == EBearerCSD || + iConnInfos[index].iBearer == EBearerHSCSD || + iConnInfos[index].iBearer == EBearerWcdmaCSD || + iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCSD || + iConnInfos[index].iBearer == EBearerExternalHSCSD || + iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) + { + ret = GetNetworkRegistration_v2( aValue ); + } + else + { + aValue = ENetworkRegistrationNotAvailable; + ret = KErrNone; + } + } + break; + case KSignalStrength: + { + // SIGNAL STRENGTH + ret = KErrNotSupported; + if ( iConnInfos[index].iBearer == EBearerGPRS || + iConnInfos[index].iBearer == EBearerEdgeGPRS || + iConnInfos[index].iBearer == EBearerWCDMA || + iConnInfos[index].iBearer == EBearerCSD || + iConnInfos[index].iBearer == EBearerHSCSD || + iConnInfos[index].iBearer == EBearerWcdmaCSD || + iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCSD || + iConnInfos[index].iBearer == EBearerExternalHSCSD || + iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) + { + ret = GetGSMSignalStrength( aValue ); + } + else if ( iConnInfos[index].iBearer == EBearerWLAN ) + { + if ( iWlanSupport ) + { + ret = iWlanSupport->GetSignalStrengthL( aMessage, aValue ); + } + } + } + break; + + case KNetworkMode: + // NETWORK MODE + ret = KErrNotSupported; + if ( iConnInfos[index].iBearer == EBearerWLAN ) + { + if ( iWlanSupport ) + { + ret = iWlanSupport->GetConnectionMode( aValue ); + } + } + break; + + case KSecurityMode: + // SECURITY MODE + ret = KErrNotSupported; + if ( iConnInfos[index].iBearer == EBearerWLAN ) + { + if ( iWlanSupport ) + { + ret = iWlanSupport->GetConnectionSecurity( aValue ); + } + } + break; + + case KTrafficClass: + ret = KErrNotSupported; + break; + case KDeliveryOrder: + ret = KErrNotSupported; + break; + case KErroneousSDUDelivery: + ret = KErrNotSupported; + break; + case KResidualBitErrorRatio: + ret = KErrNotSupported; + break; + case KSDUErrorRatio: + ret = KErrNotSupported; + break; + default: + ret = KErrArgument; + break; + } + + LOGEXITFN1("CConnMonIAP::GetIntAttributeL()", ret) + return ret; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetBearerInfo +// Returns the integer attribute in aValue +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetBearerInfo( const TUint aConnectionId, TBearerInfo& aBearerInfo ) + { + LOGENTRFN("CConnMonIAP::GetBearerInfo()") + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + err = KErrNotFound; + } + else + { + // Find out bearer if not already set. This can be only with internal + // connections. + if ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoUnknown ) + { + LOGIT("GetBearerInfo: EBearerInfoUnknown") + err = GetBearer( + aConnectionId, + iConnInfos[index].iBearer, + iConnInfos[index].iBearerInfo ); + } + if ( KErrNone == err ) + { + // Bearer is never unknown for the external connections but + // sometimes it is not valid (e.g. CSD/HSCSD) until connection + // reaches certain status. + if ( !iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoCSD || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSCSD || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoWcdmaCSD ) ) + { + if ( iCsdFax ) + { + LOGIT("GetBearerInfo: case iCsdFax") + err = iCsdFax->GetBearer( + iConnInfos[index].iBearer, + iConnInfos[index].iBearerInfo ); + } + } + else if ( !iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoGPRS || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoEdgeGPRS || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoWCDMA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) + { + if ( iPsdFax ) + { + LOGIT("GetBearerInfo: case iPsdFax") + err = iPsdFax->GetBearer( + iConnInfos[index].iBearer, + iConnInfos[index].iBearerInfo ); + } + } + else if ( iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoCSD || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSCSD || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoGPRS || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoEdgeGPRS || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoWCDMA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) + { + // CSD/HSCSD info could change after the first query also + // GPRS/EdgeGPRS/WCDMA info can change. + TInt bearer( EBearerUnknown ); + TBearerInfo bearerInfo; + + LOGIT("GetBearerInfo: GetBearer() 2nd query") + err = GetBearer( aConnectionId, bearer, bearerInfo ); + if ( ( KErrNone == err ) && ( bearerInfo.iBearer != EBearerInfoUnknown ) ) + { + iConnInfos[index].iBearer = bearer; + iConnInfos[index].iBearerInfo = bearerInfo; + } + } + } + if ( KErrNone == err ) + { + aBearerInfo.iBearer = iConnInfos[index].iBearerInfo.iBearer; + aBearerInfo.iInternal = iConnInfos[index].iBearerInfo.iInternal; + LOGIT2("GetBearerInfo: result: bearer %d, internal %d", aBearerInfo.iBearer, aBearerInfo.iInternal) + } + } + + LOGEXITFN1("CConnMonIAP::GetBearerInfo()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetUintAttributeL +// Returns the unsigned integer attribute in aValue +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetUintAttributeL( const RMessage2& aMessage, TUint& aValue ) + { + LOGENTRFN("CConnMonIAP::GetUintAttributeL()") + TInt err( KErrNone ); + TUint connectionId( aMessage.Int0() ); + TUint attribute( aMessage.Int2() ); + + LOGIT2("SERVER: CConnMonIAP::GetUintAttributeL: connId %d, attribute %d", connectionId, attribute) + + // Find connection matching the given ID + TInt index = Index( connectionId ); + if ( index < 0 ) + { + LOGEXITFN1("CConnMonIAP::GetUintAttributeL()", KErrNotFound) + return KErrNotFound; + } + + switch ( attribute ) + { + case KIAPId: + { + err = KErrNotSupported; + if ( iConnInfos[index].iBearer < EBearerExternalCSD && + iConnInfos[index].iBearerInfo.iInternal ) + { + err = KErrNone; + aValue = iConnInfos[index].iIapId; + LOGIT1("GetUintAttributeL: iap id %d", aValue) + } + } + break; + + case KNetworkIdentifier: + { + err = KErrNotSupported; + if ( iConnInfos[index].iBearer < EBearerExternalCSD && + iConnInfos[index].iBearerInfo.iInternal ) + { + err = KErrNone; + aValue = iConnInfos[index].iNetId; + LOGIT1("GetUintAttributeL: net id %d", aValue) + } + } + break; + + case KDownlinkData: + case KUplinkData: + { + if ( iConnInfos[index].iBearer < EBearerExternalCSD && + iConnInfos[index].iBearerInfo.iInternal ) + { + // INTERNAL + // Query data volumes asyncronously + if ( !iConnInfos[index].iDataVolumeAO ) + { + // Create an active object and add it to scheduler + iConnInfos[index].iDataVolumeAO = new( ELeave ) CDataVolume( + iServer, + iConnInfos[index].iConnAttach, + iConnInfos[index].iConnectionId ); + + iConnInfos[index].iDataVolumeAO->Construct(); + } + if ( !iConnInfos[index].iDataVolumeAO->IsActive() ) + { + iConnInfos[index].iDataVolumeAO->Receive(); // start a new request + } + // Don't complete this request yet + err = KRequestPending; + } + + else if ( iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCDMA2000 || + ( !iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) + { + // EXTERNAL PSD + if ( iPsdFax ) + { + TUint down( 0 ); + TUint up( 0 ); + err = iPsdFax->GetDataVolumes( connectionId, down, up ); + if ( KErrNone == err ) + { + if ( attribute == KDownlinkData ) + { + aValue = down; + } + else + { + aValue = up; + } + } + } + else + { + err = KErrNotFound; + } + } + + else + { + // EXTERNAL CSD + err = KErrNotSupported; + } + } + break; + + case KTransmitPower: + { + err = KErrNotSupported; + if ( iConnInfos[index].iBearer == EBearerWLAN && iWlanSupport ) + { + err = iWlanSupport->GetTransmitPower( aValue ); + LOGIT1("GetUintAttributeL: transmit power %d", aValue) + } + } + break; + + case KMaximumBitrateDownlink: + case KMaximumBitrateUplink: + case KMaximumSDUSize: + case KTransferDelay: + case KGuaranteedBitrateDownlink: + case KGuaranteedBitrateUplink: + case KTrafficHandlingPriority: + err = KErrNotSupported; + break; + + default: + err = KErrArgument; + break; + } + + LOGEXITFN1("CConnMonIAP::GetUintAttributeL()", err) + return err; + } + + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetBoolAttributeL +// Returns the TBool attribute in aValue +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetBoolAttributeL( const RMessage2& aMessage, TBool& aValue ) + { + LOGENTRFN("CConnMonIAP::GetBoolAttributeL()") + TInt err( KErrNone ); + TUint connectionId( aMessage.Int0() ); + TUint attribute( aMessage.Int2() ); + + switch ( attribute ) + { + case KConnectionActive: + { + // Find connection matching the given ID + TInt index = Index( connectionId ); + if ( index < 0 ) + { + LOGIT("GetBoolAttributeL: connection id not found") + err = KErrNotFound; + break; + } + if ( iConnInfos[index].iBearer < EBearerExternalCSD && + iConnInfos[index].iBearerInfo.iInternal ) + { + TInt connectionStatus( 0 ); + GetConnectionStatus( index, connectionStatus ); + LOGIT1("GetBoolAttributeL: connection status %d", connectionStatus) + + if ( connectionStatus != KLinkLayerOpen ) + { + aValue = EFalse; + break; + } + if ( ( iCountListeners > 0 ) && ( iConnInfos[index].iActivityNotifier != 0 ) ) + { + if ( iConnInfos[index].iActivityNotifier->IsActive() ) + { + // Notifications are ON and are updating the activity info. + // Return the info immediately from internal table + if ( iConnInfos[index].iActivity == 0 ) + { + aValue = EFalse; + } + else + { + aValue = ETrue; + } + } + else + { + GetActivityOneShotL( index ); + err = KRequestPending; + } + } + else + { + // Notifications are OFF + GetActivityOneShotL( index ); + err = KRequestPending; + } + } + else + { + err = KErrNotSupported; + } + } + break; + + case KBearerAvailability: + { + TUint bearer( EBearerIdAll ); + err = BearerIdForBearerAvailability( connectionId, bearer ); + if ( KErrNone == err ) + { + if ( bearer == EBearerIdWLAN ) + { + if ( iWlanSupport ) + { + err = iWlanSupport->GetBearerAvailabilityL( aMessage, aValue ); + } + else + { + err = KErrNotSupported; + } + } + else + { + TBool byCell( EFalse ); + TBool byPhone( EFalse ); + err = GetBearerSupportInfo( bearer, byCell, byPhone ); + if ( byCell && byPhone ) + { + aValue = ETrue; + } + else + { + aValue = EFalse; + } + } + } + } + break; + + case KPacketDataAvailability: + { + if ( connectionId != EBearerIdGPRS && connectionId != EBearerIdWCDMA ) + { + err = KErrNotSupported; + } + else + { + // When not in dual mode and call is active, gprs and wcdma bearers are unavailable + // Note that even the WCDMA can be unavailable, if the phone doesn't support DTM + if ( iTelephonyNotifier && iDualTransferModeNotifier && + iTelephonyNotifier->IsCallActive() && + !iDualTransferModeNotifier->IsInDualMode() ) + { + LOGIT("SERVER: Packet data UNAVAILABLE (2G&3G), no DTM and call is active") + aValue = EFalse; + } + // If DTM status says available, lets check the availability of the bearer. + // This is done because the DTM status remains as it was if the psd link is broken. + // So there might be a situation where the notifier says we are in dual mode even + // though the whole bearer is unavailable + else + { + TBool byPhone( EFalse ); + TBool byCell( EFalse ); + err = GetBearerSupportInfo( connectionId, byCell, byPhone ); + LOGIT4("Bearer support: bearer %d, byCell %d, byPhone %d, err <%d>", connectionId, byCell, byPhone, err) + aValue = ETrue; + if ( KErrNone == err ) + { + if ( byCell && byPhone ) + { + LOGIT("SERVER: Packet data AVAILABLE, DTM or no call is active") + } + else + { + LOGIT("SERVER: Packet data UNAVAILABLE, no bearer") + aValue = EFalse; + } + } + } + } + } + break; + + default: + // Unknown attribute + err = KErrArgument; + break; + } + + LOGEXITFN1("CConnMonIAP::GetBoolAttributeL()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetStringAttribute +// Returns the TDes attribute in aValue +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetStringAttribute( const RMessage2& aMessage, TDes& aValue ) + { + LOGENTRFN("CConnMonIAP::GetStringAttribute()") + TInt err( KErrNone ); + TUint connectionId( aMessage.Int0() ); + TUint attribute( aMessage.Int2() ); + + // Find connection matching the given ID + TInt index = Index( connectionId ); + if ( index < 0 ) + { + LOGEXITFN1("CConnMonIAP::GetStringAttribute()", KErrNotFound) + return KErrNotFound; + } + + // Find out bearer if not already set + if ( iConnInfos[index].iBearer == EBearerUnknown ) + { + err = GetBearer( connectionId, iConnInfos[index].iBearer, iConnInfos[index].iBearerInfo ); + if ( KErrNone != err ) + { + LOGEXITFN1("CConnMonIAP::GetStringAttribute()", err) + return err; + } + } + + switch ( attribute ) + { + case KIAPName: + { + // From RConnection + if ( iConnInfos[index].iBearer >= EBearerExternalCSD && + !iConnInfos[index].iBearerInfo.iInternal ) + { + err = KErrNotSupported; + } + else + { + TBuf settingName; + settingName.Copy( TPtrC( IAP ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( COMMDB_NAME ) ); + // IAP name max. length in commsdat should be 50 + err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), aValue ); + } + } + break; + + case KAccessPointName: + { + if ( iConnInfos[index].iBearer < EBearerExternalCSD ) + { + err = GetAccessPointName( iConnInfos[index].iConnectionId, aValue ); + } + else if ( iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + ( !iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) + { + if ( iPsdFax ) + { + err = iPsdFax->GetApn( connectionId, aValue ); + } + else + { + err = KErrNotFound; + } + } + else + { + err = KErrNotSupported; + } + } + break; + + case KTelNumber: + { + if ( iConnInfos[index].iBearer < EBearerExternalCSD ) + { + err = GetTelNumber( iConnInfos[index].iConnectionId, aValue ); + } + else if ( iConnInfos[index].iBearer == EBearerExternalCSD || + iConnInfos[index].iBearer == EBearerExternalHSCSD || + iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) + { + if ( iCsdFax ) + { + err = iCsdFax->GetTelNumber( aValue ); + } + else + { + err = KErrNotFound; + } + } + else + { + err = KErrNotSupported; + } + } + break; + + case KNetworkName: + { + err = KErrNotSupported; + if ( iConnInfos[index].iBearer == EBearerWLAN ) + { + if ( iWlanSupport ) + { + // Max SSID length is 32 + err = iWlanSupport->GetConnectionSsid( aValue ); + } + } + } + break; + + default: + err = KErrArgument; + break; + } + + LOGEXITFN1("CConnMonIAP::GetStringAttribute()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetUids +// RConnection::EnumerateConnections() must be called to get the right +// RConnection index for the connection (iConnInfos can't be trusted because +// connections are added by events, too). +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetUids( + const TUint aConnectionId, + TConnMonClientEnum& aClientEnum ) + { + TInt err( KErrNone ); + TConnEnumArgBuf enumArgBuf; + TConnGetClientInfoArgBuf clientInfoBuf; + TUint count( 0 ); + TConnectionInfoBuf connInfoBuf; + TUint j; + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + // Uids are not available for external connections + if ( iConnInfos[index].iBearer >= EBearerExternalCSD && + !iConnInfos[index].iBearerInfo.iInternal ) + { + return KErrNotSupported; + } + + // Get RConnection index for the connection + err = iConnection.EnumerateConnections( count ); + + if ( err != KErrNone ) + { + return( err ); + } + + for ( j = 1; j <= count; j++ ) + { + err = iConnection.GetConnectionInfo( j, connInfoBuf ); + + if ( err != KErrNone ) + { + return( err ); + } + + if ( ( iConnInfos[index].iIapId == connInfoBuf().iIapId ) && + ( iConnInfos[index].iNetId == connInfoBuf().iNetId ) ) + { + break; + } + } + + // If connection does not exist anymore + if ( j > count ) + { + return KErrNotFound; + } + + enumArgBuf().iIndex = j; + + // Get the number of clients + err = iConnection.Control( KCOLConnection, KCoEnumerateConnectionClients, enumArgBuf ); + + if ( err != KErrNone ) + { + return err; + } + + aClientEnum.iCount = enumArgBuf().iCount; + + // Count connection monitor OUT of the number of clients + if ( aClientEnum.iCount > 0 ) + { + --aClientEnum.iCount; + } + + // Get client uids one by one + // Note. in WINS uids are zero. + TInt k( 0 ); + + for ( TUint i = 1; i <= enumArgBuf().iCount; i++ ) + { + clientInfoBuf().iIndex = i; + + err = iConnection.Control( KCOLConnection, KCoGetConnectionClientInfo, clientInfoBuf ); + + if ( err != KErrNone ) + { + return err; + } + + // Exclude Connection Monitor UID + if ( ( clientInfoBuf().iClientInfo.iUid.iUid != KConnMonDllUid.iUid ) && + ( clientInfoBuf().iClientInfo.iUid.iUid != KGenericDllUid.iUid ) && + ( clientInfoBuf().iClientInfo.iUid.iUid != KConnMonServerUid.iUid ) && + ( clientInfoBuf().iClientInfo.iUid.iUid != 0 ) ) + { + TInt m( 0 ); + + // Look for duplicates + for ( m = 0; m < k; m++ ) + { + if ( aClientEnum.iUid[m].iUid == clientInfoBuf().iClientInfo.iUid.iUid ) + { + break; + } + } + + if ( m == k ) + { + // This is a new unique ID + aClientEnum.iUid[k].iUid = clientInfoBuf().iClientInfo.iUid.iUid; + k++; + } + else + { + // Duplicate + --aClientEnum.iCount; + } + } + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::SetUintAttribute +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::SetUintAttribute( + const RMessage2& /*aMessage*/, + const TUint /*aValue*/ ) + { + return KErrNotSupported; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::SetBoolAttributeL +// Used for stopping the connections. +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::SetBoolAttribute( const RMessage2& aMessage ) + { + LOGENTRFN("CConnMonIAP::SetBoolAttribute()") + TInt err( KErrNone ); + TUint attribute( aMessage.Int2() ); + TBool value( aMessage.Int3() ); + + switch ( attribute ) + { + case KConnectionStop: + if ( value ) + { + // Find connection matching the given Id + TInt index = Index( aMessage.Int0() ); + if ( index < 0 ) + { + err = KErrNotFound; + } + else + { + err = StopConnection( index ); + if ( KErrCouldNotConnect == err ) + { + err = KErrNotFound; + } + } + } + break; + + case KConnectionStopAll: + if ( value ) + { + TUint i( 0 ); + TUint count( 0 ); + TUint newCount( 0 ); + + // Refresh array + err = EnumerateConnections( count ); + LOGIT2("SetBoolAttribute: KConnectionStopAll: Enumerated all connections, count %d <%d>", count, err) + if ( KErrNone == err ) + { + while ( count > 0 && i < count ) + { + // Stop (and remove if up/down event watcher is dead) the connection + err = StopConnection( i ); + if ( KErrNone != err ) + { + LOGIT2("SetBoolAttribute: KConnectionStopAll: Error stopping connection %d <%d>", i, err) + return err; + } + newCount = iConnInfos.Count(); + if ( count > newCount ) + { + count = newCount; // Connection has been removed + } + else + { + i++; // Cconnection has not been removed, increment index to next connection + } + } + } + } + break; + + default: + err = KErrArgument; + break; + } + + LOGEXITFN1("CConnMonIAP::SetBoolAttribute()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::SetStringAttributeL +// +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::SetStringAttributeL( + const RMessage2& /*aMessage*/, + const TDes& /*aValue*/ ) + { + return KErrNotSupported; + } + + +// ----------------------------------------------------------------------------- +// CConnMonIAP::ListenL +// Starts event watchers. +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::ListenL() + { + LOGIT(".") + LOGENTRFN("CConnMonIAP::ListenL()") + iCountListeners++; + + // GLOBAL notifiers + + // Connection Up/Down events + if ( iConnUpDownNotifier == 0 ) + { + iConnUpDownNotifier = new( ELeave ) CConnUpDownNotifier( iServer ); + iConnUpDownNotifier->Construct(); + } + if ( !iConnUpDownNotifier->IsActive() ) + { + iConnUpDownNotifier->Receive(); // (re)start listening + } + + if ( iTSYLoaded && iPacketServLoaded ) + { + // PSD network status events + if ( iPsdNetwStatusNotifier == 0 ) + { + iPsdNetwStatusNotifier = CNetwStatusNotifier::NewL( iServer ); + } + if ( !iPsdNetwStatusNotifier->IsActive() ) + { + iPsdNetwStatusNotifier->Receive(); // (re)start listening + } + + // GPRS bearer availability changed events + if ( iGSMBearerAvailabilityNotifier == 0 ) + { + iGSMBearerAvailabilityNotifier = CBearerAvailabilityNotifier::NewL( iServer ); + } + if ( !iGSMBearerAvailabilityNotifier->IsActive() ) + { + iGSMBearerAvailabilityNotifier->Receive(); // (re)start listening + } + } + + if ( iTSYLoaded ) + { + // Mode change events + if ( iModeNotifier == 0 ) + { + iModeNotifier = CModeNotifier::NewL( iServer, iMobilePhone ); + } + if ( !iModeNotifier->IsActive() ) + { + iModeNotifier->Receive(); // (re)start listening + } + + // Network registration status events + if ( iNetwRegistrationNotifier == 0 ) + { + iNetwRegistrationNotifier = CNetwRegistrationNotifier::NewL( iServer, iMobilePhone ); + } + if ( !iNetwRegistrationNotifier->IsActive() ) + { + iNetwRegistrationNotifier->Receive(); // (re)start listening + } + + // Bearer change (GPRS/Edge GPRS) status events + if ( FeatureManager::FeatureSupported( KFeatureIdEdgeKnowledge ) ) + { + if ( iEdgeNotifier == 0 ) + { + iEdgeNotifier = new( ELeave ) CBearerNotifier( iServer, iMobilePhone ); + TRAPD( ret, iEdgeNotifier->ConstructL() ); + if ( ret != KErrNone ) + { + // Construction (=opening ETel CustomAPI) failed + delete iEdgeNotifier; + iEdgeNotifier = 0; + } + } + if ( iEdgeNotifier != 0 ) + { + if ( !iEdgeNotifier->IsActive() ) + { + iEdgeNotifier->Receive(); // (re)start listening + } + } + } + + if ( !iWcdmaNotifier ) + { + iWcdmaNotifier = CWcdmaBearerNotifier::NewL( iServer, iTelServer ); + if ( iWcdmaNotifier ) + { + iWcdmaNotifier->Receive(); + } + } + + if ( FeatureManager::FeatureSupported( KFeatureIdConnMonExtension ) ) + { + // GSM signal strength change events + if ( iGSMSignalNotifier == 0 ) + { + iGSMSignalNotifier = CGsmSignalNotifier::NewL( iServer, iMobilePhone ); + } + if ( !iGSMSignalNotifier->IsActive() ) + { + iGSMSignalNotifier->Receive(); // (re)start listening + } + } + } + + if ( !iTelephonyNotifier ) + { + iTelephonyNotifier = CConnMonTelNotifier::NewL( *this, &iMobilePhone ); + iTelephonyNotifier->Receive(); + } + + if ( !iDualTransferModeNotifier && iPacketServLoaded ) + { + iDualTransferModeNotifier = CConnMonDtmNotifier::NewL( iPacketService, *this ); + iDualTransferModeNotifier->Receive(); + } + + if ( iWlanSupport ) + { + iWlanSupport->EnableEventsToClients(); + } + + // Notifiers owned by the connections + // (connection status, data volumes, connection activity, subconnection up/down) + TInt count = iConnInfos.Count(); + + for ( TInt i = 0; i < count; i++ ) + { + AddConnNotificationsL( i ); + } + LOGEXITFN("CConnMonIAP::ListenL()") + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::CancelListen +// Stops and deletes event watchers. +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::CancelListen() + { + iCountListeners--; + LOGIT1("CancelListen() remaining listeners: %d", iCountListeners) + + if ( iCountListeners == 0 ) + { + DeleteNotifications(); + } + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::AddConnectionL +// Adds a new connection to the iConnInfos array. Starts event watchers for the +// connection if there are clients that want events. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::AddConnectionL( TConnInfo& aConnection ) + { + TInt err( KErrNone ); + TInt index( KErrNotFound ); + TUint8 internal( 0 ); + + if ( aConnection.iBearer < EBearerExternalCSD ) + { + internal = 1; + } + + if ( internal ) + { + index = iConnInfos.Find( aConnection, TConnInfo::MatchIap ); + } + /* + else + { + index = iConnInfos.Find( aConnection, TConnInfo::MatchBearer ); + } + */ + + if ( KErrNotFound != index ) + { + LOGIT("AddConnectionL: New connection occured with same IAP id, remove old") + // To remove the connection we have to complete the + // connection by sending the notifications needed by clients. + CompleteConnectionClosing( index ); + } + + // Add to connection table + aConnection.iConnectionId = NewConnectionId(); + + if ( internal ) + { + err = OpenAndAttachTo( aConnection ); + if ( err != KErrNone ) + { + LOGIT1("AddConnectionL: ERROR attach failed <%d>", err) + return err; + } + } + + err = iConnInfos.Append( aConnection ); + + if ( ( KErrNone == err ) && internal ) + { + index = iConnInfos.Find( aConnection, TConnInfo::MatchIap ); + if ( ( index != KErrNotFound ) && ( iCountListeners > 0 ) ) + { + TRAPD( ret, AddConnNotificationsL( index ) ); + if ( ret != KErrNone ) + { + // Close attached connection + if ( iConnInfos[ index ].iConnAttach != 0 ) + { + iConnInfos[ index ].iConnAttach->Close(); + delete iConnInfos[ index ].iConnAttach; + } + + // Remove + iConnInfos.Remove( index ); + + // Leave + User::Leave( ret ); + } + } + } + + // Print connection info array to log + #ifdef _DEBUG + LOGIT("AddConnectionL: Connection info array:") + for ( TInt m = 0; m < iConnInfos.Count(); m++ ) + { + LOGIT4(" id %d, bearer %d, iapId %d, netId %d", iConnInfos[m].iConnectionId, + iConnInfos[m].iBearer, iConnInfos[m].iIapId, iConnInfos[m].iNetId) + } + #endif // _DEBUG + + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::CompleteConnectionClosing +// ----------------------------------------------------------------------------------- +// +void CConnMonIAP::CompleteConnectionClosing( TInt& aIndex ) + { + LOGENTRFN("CConnMonIAP::CompleteConnectionClosing()") + + if ( iConnInfos[aIndex].iBearerNotifier->Listening() ) + { + iConnInfos[aIndex].iBearerNotifier->CancelListen(); + } + + if ( iConnInfos[aIndex].iProgressNotifier->IsActive() ) + { + // Progress notification request is still active --> Cancel it + iConnInfos[aIndex].iProgressNotifier->Cancel(); + } + // Send KLinkLayerClosed event + LOGIT("CompleteConnectionClosing: ProgressNotifier->SendClosedEvent()") + iConnInfos[aIndex].iProgressNotifier->SendClosedEvent(); + + if ( iConnInfos[aIndex].iConnDownNotifier->IsActive() ) + { + // Allinterface notification request is still active --> Cancel it + iConnInfos[aIndex].iConnDownNotifier->Cancel(); + } + + if ( !iConnInfos[aIndex].iConnDownNotifier->DeleteSent() ) + { + // After SetInterfaceClosed() call SendDeletedEvent() removes + // the connection + iConnInfos[aIndex].iConnDownNotifier->SetInterfaceClosed(); + iConnInfos[aIndex].iConnDownNotifier->SendDeletedEvent(); + } + else + { + // Delete has already been sent (shouldn't be possible) so + // connection has to be removed + LOGIT("CompleteConnectionClosing: Delete already sent, removing connection") + RemoveConnection( iConnInfos[aIndex] ); + } + + LOGEXITFN("CConnMonIAP::CompleteConnectionClosing()") + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::RemoveConnection +// Removes connection settings from sessions, stops and deletes event watchers and +// removes the connection info from the iConnInfos array. +// Connection is deleted by an event (or by calling RConnection::Stop()). +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::RemoveConnection( TConnInfo& aConnection ) + { + LOGENTRFN("CConnMonIAP::RemoveConnection()") + + TInt index( KErrNotFound ); + // Check if bearer is external CSD + if ( aConnection.iBearer == EBearerExternalCSD || + aConnection.iBearer == EBearerExternalHSCSD || + aConnection.iBearer == EBearerExternalWcdmaCSD ) + { + index = iConnInfos.Find( aConnection, TConnInfo::MatchBearer ); + } + else if ( aConnection.iConnectionId > 0 ) + { + index = iConnInfos.Find( aConnection, TConnInfo::MatchId ); + } + else + { + index = iConnInfos.Find( aConnection, TConnInfo::MatchIap ); + } + + TInt err( KErrNotFound ); + if ( index >= 0 ) + { + // Set connection id for passing it back to the caller (client event) + aConnection.iConnectionId = iConnInfos[index].iConnectionId; + + // Remove threshold settings from the client tables + iServer->RemoveConnSettingsFromSessions( aConnection.iConnectionId ); + + // Stop notifications (data volume, connection status, etc.) + DeleteConnNotifications( index ); + + // Close attached connection + if ( iConnInfos[index].iConnAttach != 0 ) + { + iConnInfos[index].iConnAttach->Close(); + delete iConnInfos[index].iConnAttach; + iConnInfos[index].iConnAttach = NULL; + } + + iConnInfos.Remove( index ); + err = KErrNone; + } + + // Print connection info array to log + #ifdef _DEBUG + LOGIT("RemoveConnection: Connection info array:") + for ( TInt m = 0; m < iConnInfos.Count(); m++ ) + { + LOGIT4(" id %d, bearer %d, iapId %d, netId %d", iConnInfos[m].iConnectionId, + iConnInfos[m].iBearer, iConnInfos[m].iIapId, iConnInfos[m].iNetId) + } + #endif // _DEBUG + + LOGEXITFN1("CConnMonIAP::RemoveConnection()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::CalculateNetworkStatus +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::CalculateNetworkStatus( const RPacketService::TStatus& aPacketStatus ) const + { + switch ( aPacketStatus ) + { + case ( RPacketService::EStatusUnattached ): + return EConnMonStatusUnattached; + + case ( RPacketService::EStatusAttached ): + return EConnMonStatusAttached; + + case ( RPacketService::EStatusActive ): + return EConnMonStatusActive; + + case ( RPacketService::EStatusSuspended ): + return EConnMonStatusSuspended; + + default: + break; + } + return aPacketStatus; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::CalculateNetworkRegistration +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::CalculateNetworkRegistration( + const RMobilePhone::TMobilePhoneRegistrationStatus& + aRegistration ) const + { + switch ( aRegistration ) + { + case ( RMobilePhone::ERegistrationUnknown ): + return ENetworkRegistrationUnknown; + + case ( RMobilePhone::ENotRegisteredNoService ): + return ENetworkRegistrationNoService; + + case ( RMobilePhone::ENotRegisteredEmergencyOnly ): + return ENetworkRegistrationEmergencyOnly; + + case ( RMobilePhone::ENotRegisteredSearching ): + return ENetworkRegistrationSearching; + + case ( RMobilePhone::ERegisteredBusy ): + return ENetworkRegistrationBusy; + + case ( RMobilePhone::ERegisteredOnHomeNetwork ): + return ENetworkRegistrationHomeNetwork; + + case ( RMobilePhone::ERegistrationDenied ): + return ENetworkRegistrationDenied; + + case ( RMobilePhone::ERegisteredRoaming ): + return ENetworkRegistrationRoaming; + + default: + break; + } + return aRegistration; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::CalculateNetworkRegistration_v2 +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::CalculateNetworkRegistration_v2( + const RMobilePhone::TMobilePhoneRegistrationStatus& + aRegistration ) const + { + switch ( aRegistration ) + { + case ( RMobilePhone::ERegistrationUnknown ): + return ENetworkRegistrationExtUnknown; + + case ( RMobilePhone::ENotRegisteredNoService ): + return ENetworkRegistrationExtNoService; + + case ( RMobilePhone::ENotRegisteredEmergencyOnly ): + return ENetworkRegistrationExtEmergencyOnly; + + case ( RMobilePhone::ENotRegisteredSearching ): + return ENetworkRegistrationExtSearching; + + case ( RMobilePhone::ERegisteredBusy ): + return ENetworkRegistrationExtBusy; + + case ( RMobilePhone::ERegisteredOnHomeNetwork ): + return ENetworkRegistrationExtHomeNetwork; + + case ( RMobilePhone::ERegistrationDenied ): + return ENetworkRegistrationExtDenied; + + case ( RMobilePhone::ERegisteredRoaming ): + { + RMobilePhone::TMobilePhoneNetworkInfoV1 network; + RMobilePhone::TMobilePhoneNetworkInfoV1Pckg networkPckg( network ); + + RMobilePhone::TMobilePhoneNetworkInfoV1 homeNetwork; + RMobilePhone::TMobilePhoneNetworkInfoV1Pckg homeNetworkPckg( homeNetwork ); + + TRequestStatus status( KErrNone ); + + iMobilePhone.GetCurrentNetwork(status, networkPckg); + User::WaitForRequest( status ); + + if(status.Int() == KErrNone) + { + iMobilePhone.GetHomeNetwork(status, homeNetworkPckg); + User::WaitForRequest( status ); + + if(network.iCountryCode.Compare(homeNetwork.iCountryCode) == 0) + { + return ENetworkRegistrationExtRoamingNational; + } + else + { + return ENetworkRegistrationExtRoamingInternational; + } + } + } + + default: + break; + } + return aRegistration; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::IsEdgeCell +// ----------------------------------------------------------------------------- +// +TBool CConnMonIAP::IsEdgeCell() + { + LOGENTRFN("CConnMonIAP::IsEdgeCell()") + TBool edgeStatus( EFalse ); + + LOGTIMINGSTART("CConnMonIAP::IsEdgeCell") + + if ( FeatureManager::FeatureSupported( KFeatureIdEdgeKnowledge ) ) + { + RMmCustomAPI customApi; + RMmCustomAPI::TGprsInformation gprsInfo; + RMmCustomAPI::TGprsInformationPckg gprsInfoPckg( gprsInfo ); + TRequestStatus status( KErrNone ); + + TInt ret = customApi.Open( iMobilePhone ); + + if ( KErrNone == ret ) + { + customApi.GetEGprsInfo( status, gprsInfoPckg ); + User::WaitForRequest( status ); + + customApi.Close(); + + if ( KErrNone == status.Int() ) + { + if ( gprsInfoPckg().iGprsInfo == RMmCustomAPI::EEdgeGprs ) + { + edgeStatus = ETrue; + } + } + else + { + LOGIT1("IsEdgeCell: Error, RMmCustomAPI.GetEGprsInfo() <%d>", status.Int()) + } + } + else + { + LOGIT1("IsEdgeCell: Error, RMmCustomAPI.Open() <%d>", ret) + } + } + else + { + LOGIT("IsEdgeCell: KFeatureIdEdgeKnowledge not supported") + } + LOGTIMINGEND("CConnMonIAP::IsEdgeCell") + + LOGEXITFN1("CConnMonIAP::IsEdgeCell()", (TInt)edgeStatus) + return edgeStatus; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::IsHsdpaCell +// ----------------------------------------------------------------------------- +// +TBool CConnMonIAP::IsHsdpaCell() + { + LOGENTRFN("CConnMonIAP::IsHsdpaCell()") + + RPacketService::TDynamicCapsFlags dynamicCaps( 0 ); + TBool hsdpaStatus( EFalse ); + + LOGTIMINGSTART("CConnMonIAP::IsHsdpaCell") + + TInt ret = iPacketService.GetDynamicCaps( dynamicCaps ); + if ( dynamicCaps & RPacketService::KCapsHSDPA ) + { + hsdpaStatus = ETrue; + } + LOGTIMINGEND("CConnMonIAP::IsHsdpaCell") + LOGIT2("IsHsdpaCell: Dynamic caps 0x%06X <%d>", dynamicCaps, ret) + + LOGEXITFN1("CConnMonIAP::IsHsdpaCell()", (TInt)hsdpaStatus) + return hsdpaStatus; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::HsxpaStatus +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::HsxpaStatus() + { + LOGENTRFN("CConnMonIAP::HsxpaStatus()") + + RPacketService::TDynamicCapsFlags dynamicCaps( 0 ); + TInt hspaState( EBearerInfoWCDMA ); + + LOGTIMINGSTART("CConnMonIAP::HsxpaStatus") + + TInt ret = iPacketService.GetDynamicCaps( dynamicCaps ); + if ( dynamicCaps & RPacketService::KCapsHSDPA ) + { + if ( dynamicCaps & RPacketService::KCapsHSUPA ) + { + hspaState = EBearerInfoHSxPA; + } + else + { + hspaState = EBearerInfoHSDPA; + } + } + else + { + if ( dynamicCaps & RPacketService::KCapsHSUPA ) + { + hspaState = EBearerInfoHSUPA; + } + else + { + hspaState = EBearerInfoWCDMA; + } + } + LOGTIMINGEND("CConnMonIAP::HsxpaStatus") + LOGIT2("HsxpaStatus: Dynamic caps 0x%06X <%d>", dynamicCaps, ret) + + LOGEXITFN1("CConnMonIAP::HsxpaStatus()", hspaState) + return hspaState; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetStartTime +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetStartTime( const TUint& aConnectionId, TTime& aTime ) + { + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( iConnInfos[index].iBearer < EBearerExternalCSD + && iConnInfos[index].iBearerInfo.iBearer <= EBearerInfoHSxPA ) + { + // INTERNAL CONNECTIONS + TUint subConnectionCount( 0 ); + + // Find the start time of the earliest subconnection + err = iConnInfos[index].iConnAttach->EnumerateSubConnections( subConnectionCount ); + + if ( KErrNone != err ) + { + return err; + } + + LOGIT1("GetStartTime: Sub connection count %d", subConnectionCount) + for ( TUint i = 1; i <= subConnectionCount; i++ ) + { + TSubConnectionInfo subInfo; + TPckg pckgSubInfo( subInfo ); + + err = iConnInfos[index].iConnAttach->GetSubConnectionInfo( i, pckgSubInfo ); + + if ( KErrNone != err ) + { + LOGIT2("GetStartTime: Error getting conn.info for index %d, <%d>", i, err) + return err; + } + + if ( i == 1 ) + { + aTime = pckgSubInfo().iTimeStarted; + } + else if ( aTime > pckgSubInfo().iTimeStarted ) + { + aTime = pckgSubInfo().iTimeStarted; + } + } + } + else if ( iConnInfos[index].iBearer == EBearerExternalGPRS || + iConnInfos[index].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[index].iBearer == EBearerExternalWCDMA || + iConnInfos[index].iBearer == EBearerExternalCDMA2000 || + ( !iConnInfos[index].iBearerInfo.iInternal && + ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) + { + // EXTERNAL PSD + if ( iPsdFax ) + { + err = iPsdFax->GetStartTime( aConnectionId, aTime ); + + if ( KErrNone != err ) + { + return err; + } + } + else + { + return KErrNotFound; + } + } + else if ( iConnInfos[index].iBearer == EBearerExternalCSD || + iConnInfos[index].iBearer == EBearerExternalHSCSD || + iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) + { + // EXTERNAL CSD + if ( iCsdFax ) + { + err = iCsdFax->GetStartTime( aTime ); + + if ( KErrNone != err ) + { + return err; + } + } + else + { + err = KErrNotFound; + } + } + else + { + return KErrNotSupported; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetBearer +// Gets the bearer setting for the internal connections. +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetBearer( + const TUint& aConnectionId, + TInt& aBearer, + TBearerInfo& aBearerInfo ) + { + TInt err( KErrNone ); + TUint32 bearerType( EBearerUnknown ); + TBuf settingName; + TBuf settingValue; + + LOGENTRFN("CConnMonIAP::GetBearer()") + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + LOGEXITFN1("CConnMonIAP::GetBearer()", KErrNotFound) + return KErrNotFound; + } + + if ( iConnInfos[index].iConnAttach == 0 ) + { + LOGIT("GetBearer: error, iConnAttach was NULL") + LOGEXITFN1("CConnMonIAP::GetBearer()", KErrArgument) + return KErrArgument; + } + + // Find out BEARER TYPE + settingName.Copy( TPtrC( IAP ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( IAP_BEARER_TYPE ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), settingValue ); + if ( KErrNone != err ) + { + LOGIT1("GetBearer: ERROR getting IAP bearer type <%d>", err) + LOGEXITFN1("CConnMonIAP::GetBearer()", err) + return err; + } + + if ( settingValue == TPtrC( VIRTUAL_BEARER ) ) + { + aBearer = EBearerVirtual; + aBearerInfo.iBearer = EBearerInfoVirtual; + aBearerInfo.iInternal = ETrue; + } + + // Find out SERVICE TYPE + settingName.Copy( TPtrC( IAP ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( IAP_SERVICE_TYPE ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), settingValue ); + if ( KErrNone != err ) + { + LOGIT1("GetBearer: ERROR getting IAP service type <%d>", err) + LOGEXITFN1("CConnMonIAP::GetBearer()", err) + return err; + } + + // Is this virtual bearer + VPN service + if ( ( aBearer == EBearerVirtual ) && ( settingValue == TPtrC( VPN_SERVICE ) ) ) + { + aBearer = EBearerVirtualVPN; + aBearerInfo.iBearer = EBearerInfoVirtualVPN; + aBearerInfo.iInternal = ETrue; + } + + // Return if bearer has been solved + if ( aBearer != EBearerUnknown ) + { + LOGEXITFN1("CConnMonIAP::GetBearer()", KErrNone) + return KErrNone; + } + + // Study service type if bearer is still unknown + if ( settingValue == TPtrC( DIAL_OUT_ISP ) || settingValue == TPtrC( DIAL_IN_ISP ) ) + { + LOGIT("GetBearer: type is dial_x_isp") + settingName.Copy( settingValue ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( ISP_BEARER_TYPE ) ); + + err = iConnInfos[index].iConnAttach->GetIntSetting( TPtrC( settingName ), bearerType ); + + if ( KErrNone != err ) + { + return err; + } + + if ( bearerType == EBearerTypeCSD ) + { + aBearer = EBearerCSD; + aBearerInfo.iBearer = EBearerInfoCSD; + aBearerInfo.iInternal = ETrue; + } + else + { + // EBearerTypeHSCSD + aBearer = EBearerHSCSD; + aBearerInfo.iBearer = EBearerInfoHSCSD; + aBearerInfo.iInternal = ETrue; + } + + if ( iTSYLoaded ) + { + RMobilePhone::TMobilePhoneNetworkMode mode; + + err = iMobilePhone.GetCurrentMode( mode ); + + if ( ( KErrNone == err ) && ( mode == RMobilePhone::ENetworkModeWcdma ) ) + { + aBearer = EBearerWcdmaCSD; + aBearerInfo.iBearer = EBearerInfoWcdmaCSD; + aBearerInfo.iInternal = ETrue; + } + } + + if ( aBearer == EBearerHSCSD || aBearer == EBearerCSD ) + { + // If TsyName == PHONETSY try to find out the real life situation (CSD/HSCSD) from ETel + // For point-to-point connections TSY is NOT PHONETSY. + settingName.Copy( TPtrC( IAP ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( IAP_BEARER_TYPE ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( + TPtrC( settingName ), + settingValue ); + + if ( ( KErrNone == err ) && ( settingValue == TPtrC( MODEM_BEARER ) ) ) + { + settingName.Copy( TPtrC( MODEM_BEARER ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( MODEM_TSY_NAME ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( + TPtrC( settingName ), + settingValue ); + + TBuf tmp( KMmTsyModuleName ); + tmp.UpperCase(); + + if ( ( KErrNone == err ) && ( settingValue == tmp ) ) + { + // TSY is PHONETSY + TBuf number; + + err = GetTelNumber( aConnectionId, number ); + + if ( KErrNone == err ) + { + GetBearerFromETel( number, aBearer, aBearerInfo ); + } + } + } + } + } + else if ( settingValue == TPtrC( OUTGOING_WCDMA ) || + settingValue == TPtrC( INCOMING_WCDMA ) ) + { + LOGIT("GetBearer: type is wcdma") + if ( iTSYLoaded ) + { + RMobilePhone::TMobilePhoneNetworkMode mode; + err = iMobilePhone.GetCurrentMode( mode ); + LOGIT2("GetBearer: phone mode %d <%d>", (TInt)mode, err) + if ( ( KErrNone != err ) || + ( mode == RMobilePhone::ENetworkModeUnknown ) || + ( mode == RMobilePhone::ENetworkModeUnregistered ) ) + { + // MODE is UNKNOWN + LOGIT2("GetBearer: mode is unknown %d <%d>", mode, err) + if ( FeatureManager::FeatureSupported( KFeatureIdProtocolGsm ) ) + { + // KFeatureIdProtocolGsm means that phone supports only GSM + if ( IsEdgeCell() ) + { + aBearer = EBearerEdgeGPRS; + aBearerInfo.iBearer = EBearerInfoEdgeGPRS; + } + else + { + aBearer = EBearerGPRS; + aBearerInfo.iBearer = EBearerInfoGPRS; + } + aBearerInfo.iInternal = ETrue; + } + else + { + LOGIT("GetBearer: KFeatureIdProtocolGsm not supported") + } + } + else + { + // MODE is KNOWN + if ( mode == RMobilePhone::ENetworkModeWcdma ) + { + aBearer = EBearerWCDMA; + aBearerInfo.iBearer = HsxpaStatus(); + aBearerInfo.iInternal = ETrue; + } + else if ( mode == RMobilePhone::ENetworkModeGsm ) + { + if ( IsEdgeCell() ) + { + aBearer = EBearerEdgeGPRS; + aBearerInfo.iBearer = EBearerInfoEdgeGPRS; + } + else + { + aBearer = EBearerGPRS; + aBearerInfo.iBearer = EBearerInfoGPRS; + } + aBearerInfo.iInternal = ETrue; + } + else + { + LOGIT1("GetBearer: error, mode was unexpected %d", mode) + } + } + } + } + + else if ( settingValue == TPtrC( LAN_SERVICE ) ) + { + LOGIT("GetBearer: type is (w)lan") + aBearer = EBearerLAN; + aBearerInfo.iBearer = EBearerInfoLAN; + aBearerInfo.iInternal = ETrue; + + settingName.FillZ(); + settingValue.FillZ(); + settingName.Copy( TPtrC( LAN_BEARER ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( COMMDB_NAME ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), settingValue ); + + if ( KErrNone != err ) + { + return err; + } + + if ( settingValue == TPtrC( KWlanBearerRecordName ) ) + { + aBearer = EBearerWLAN; + aBearerInfo.iBearer = EBearerInfoWLAN; + } + } + LOGIT2("GetBearer: bearer %d, bearerInfo %d", aBearer, aBearerInfo.iBearer) + LOGEXITFN1("CConnMonIAP::GetBearer()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::UpdateActivity +// Updates connection activity information. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::UpdateActivity( const TUint& aConnectionId, const TUint& aActivity ) + { + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( aActivity == 0 ) + { + iConnInfos[index].iActivity = 0; + } + else + { + iConnInfos[index].iActivity = 1; + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::GetDeleteNotifyStatus +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetDeleteNotifyStatus( TConnInfo& aConnection, TBool& aSent ) + { + TInt index( KErrNotFound ); + + if ( aConnection.iBearer >= EBearerExternalCSD ) + { + return KErrNotSupported; + } + + index = iConnInfos.Find( aConnection, TConnInfo::MatchIap ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + aConnection.iConnectionId = iConnInfos[index].iConnectionId; + aConnection.iBearer = iConnInfos[index].iBearer; + + TInt connectionStatus( 0 ); + GetConnectionStatus( index, connectionStatus ); + + if ( ( iConnInfos[index].iConnDownNotifier != 0 ) && + ( iConnInfos[index].iProgressNotifier != 0 ) ) + { + if ( !iConnInfos[index].iConnDownNotifier->DeleteSent() && + !iConnInfos[index].iConnDownNotifier->IsActive() && + ( !iConnInfos[index].iProgressNotifier->IsActive() || + ( connectionStatus != KLinkLayerOpen ) ) ) + { + aSent = EFalse; + } + else + { + aSent = ETrue; + } + } + else + { + aSent = EFalse; + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::GetActivityNotifier +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetActivityNotifier( + const TUint& aConnectionId, + CActivityNotifier** aActivityNotifier ) + { + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( aActivityNotifier == 0 ) + { + return KErrUnknown; + } + + *aActivityNotifier = iConnInfos[ index ].iActivityNotifier; + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::GetProgressNotifier +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetProgressNotifier( + const TUint& aConnectionId, + CProgressNotifier** aProgressNotifier ) + { + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( aProgressNotifier == 0 ) + { + return KErrUnknown; + } + + *aProgressNotifier = iConnInfos[index].iProgressNotifier; + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::GetSubConnUpDownNotifier +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetSubConnUpDownNotifier( + const TUint& aConnectionId, + CSubConnUpDownNotifier** aSubConnUpDownNotifier ) + { + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( aSubConnUpDownNotifier == 0 ) + { + return KErrUnknown; + } + + *aSubConnUpDownNotifier = iConnInfos[index].iConnDownNotifier; + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::WakeUpNotifications +// Wakes up sleeping CONNECTION SPECIFIC event watchers that depend on a threshold. +// (data volume, activity). +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::WakeUpNotifications( const TUint& aConnectionId ) + { + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( ( iConnInfos[index].iBearer < EBearerExternalCSD ) && ( iCountListeners > 0 ) ) + { + // INTERNAL CONNECTIONS + TInt connectionStatus( 0 ); + GetConnectionStatus( index, connectionStatus ); + + if ( ( connectionStatus == KLinkLayerOpen ) || ( connectionStatus == KPsdSuspended ) ) + { + // ------------------------- + // Amount of Downlink data + // ------------------------- + if ( iConnInfos[index].iDLDataNotifier != 0 ) + { + if ( !iConnInfos[index].iDLDataNotifier->IsActive() ) + { + iConnInfos[index].iDLDataNotifier->Receive(); // (re)start listening + } + } + + // ------------------------- + // Amount of Uplink data + // ------------------------- + if ( iConnInfos[index].iULDataNotifier != 0 ) + { + if ( !iConnInfos[index].iULDataNotifier->IsActive() ) + { + iConnInfos[index].iULDataNotifier->Receive(); // (re)start listening + } + } + + // ---------------------- + // Connection Activity + // ---------------------- + if ( iConnInfos[index].iActivityNotifier != 0 ) + { + if ( !iConnInfos[index].iActivityNotifier->IsActive() ) + { + iConnInfos[index].iActivityNotifier->Receive( iConnInfos[index].iActivity ); + } + } + + if ( iConnInfos[index].iBearerNotifier ) + { + if ( !iConnInfos[index].iBearerNotifier->Listening() ) + { + iConnInfos[index].iBearerNotifier->Listen(); + } + } + } + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::WakeUpNotifications +// Wakes up GENERAL sleeping event watchers that depend on a threshold. +// (signal strength, bearer availability). +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::WakeUpNotifications() + { + if ( iGSMSignalNotifier != 0 ) + { + if ( !iGSMSignalNotifier->IsActive() ) + { + iGSMSignalNotifier->Receive(); // (re)start listening + } + } + + if ( iGSMBearerAvailabilityNotifier != 0 ) + { + if ( !iGSMBearerAvailabilityNotifier->IsActive() ) + { + iGSMBearerAvailabilityNotifier->Receive(); // (re)start listening + } + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::LaunchActivityNotifierL +// Launches the activity notifier for the given connection id. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::LaunchActivityNotifierL( const TUint& aConnectionId ) + { + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + GetActivityOneShotL( index ); + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::LaunchDataNotifiers +// Launches the data notifiers (uplink & downlink) for the given connection id. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::LaunchDataNotifiers( const TUint& aConnectionId ) + { + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( iConnInfos[index].iDLDataNotifier != 0 ) + { + if ( !iConnInfos[index].iDLDataNotifier->IsActive() ) + { + iConnInfos[index].iDLDataNotifier->Receive(); + } + } + + if ( iConnInfos[index].iULDataNotifier != 0 ) + { + if ( !iConnInfos[index].iULDataNotifier->IsActive() ) + { + iConnInfos[index].iULDataNotifier->Receive(); + } + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::LaunchDataNotifiers +// Launches the data notifiers (uplink & downlink) for the given connection id. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::LaunchBearerNotifier( const TUint& aConnectionId ) + { + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + if ( iConnInfos[index].iBearerNotifier ) + { + if ( !iConnInfos[index].iBearerNotifier->Listening() ) + { + iConnInfos[index].iBearerNotifier->Listen(); + } + } + + return KErrNone; + } + + +// ----------------------------------------------------------------------------- +// CConnMonIAP::AppendActiveConnections +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::GetActiveConnectionsIds( const TUint& aBearerId, RArray& aIdArray ) + { + //LOGENTRFN("CConnMonIAP::GetActiveConnectionsIds()") + + const TInt count = iConnInfos.Count(); + for ( TInt i = 0; i < count; i++ ) + { + // Bearer might still be uninitialized + if ( iConnInfos[i].iBearer == EBearerUnknown ) + { + LOGIT1("GetActiveConnectionsIds: bearer unknown for conn.id %d", + iConnInfos[i].iConnectionId) + TInt err = GetBearer( + iConnInfos[i].iConnectionId, + iConnInfos[i].iBearer, + iConnInfos[i].iBearerInfo ); + + if ( KErrNone != err ) + { + // Skip because bearer is unknown. This connection has not yet fully started. + continue; + } + } + switch ( iConnInfos[i].iBearer ) + { + case EBearerGPRS: + case EBearerEdgeGPRS: + case EBearerWCDMA: + { + if ( aBearerId == EBearerIdGPRS ) + { + aIdArray.Append( iConnInfos[i].iIapId ); + } + } + break; + case EBearerWLAN: + { + if ( aBearerId == EBearerIdWLAN ) + { + TInt connectionStatus( 0 ); + GetConnectionStatus( i, connectionStatus ); + if ( connectionStatus == KLinkLayerOpen ) + { + aIdArray.Append( iConnInfos[i].iIapId ); + } + } + } + break; + case EBearerCSD: + case EBearerHSCSD: + case EBearerWcdmaCSD: + { + if ( aBearerId == EBearerIdCSD ) + { + aIdArray.Append( iConnInfos[i].iIapId ); + } + } + break; + case EBearerLAN: + { + if ( aBearerId == EBearerIdLAN ) + { + aIdArray.Append( iConnInfos[i].iIapId ); + } + } + break; + default: + break; + } + } + //LOGEXITFN("CConnMonIAP::GetActiveConnectionsIds()") + } + + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetBearerSupportInfo +// Checks whether the current cell and the phone support a bearer (GPRS or CSD). +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetBearerSupportInfo( + const TUint aConnectionId, + TBool& aByCell, + TBool& aByPhone ) const + { + LOGENTRFN("CConnMonIAP::GetBearerSupportInfo()") + TInt err( KErrNone ); + + aByCell = EFalse; + aByPhone = EFalse; + + if ( !iTSYLoaded ) + { + LOGIT("GetBearerSupportInfo: ERROR, TSY not loaded") + LOGEXITFN1("CConnMonIAP::GetBearerSupportInfo()", err) + return err; + } + + RPacketService::TDynamicCapsFlags capsDynamic( 0 ); + if ( iPacketServLoaded ) + { + err = iPacketService.GetDynamicCaps( capsDynamic ); + if ( KErrNone != err ) + { + LOGIT1("GetBearerSupportInfo: ERROR getting dynamic caps <%d>", err) + capsDynamic = 0; + } + } + + if ( aConnectionId == EBearerIdGPRS || aConnectionId == EBearerIdWCDMA ) + { + LOGIT2("GetBearerSupportInfo: GPRS and WCDMA, dynamic caps: 0x%04X <%d>", capsDynamic, err) + + // 1. Is GPRS/WCDMA supported by this NETWORK CELL + if ( ( capsDynamic & RPacketService::KCapsManualAttach ) || + ( capsDynamic & RPacketService::KCapsManualDetach ) ) + { + // Is the phone registered on the packet network + RPacketService::TRegistrationStatus nwRegStatus( RPacketService::EUnknown ); + TRequestStatus status( KErrNone ); + iPacketService.GetNtwkRegStatus( status, nwRegStatus ); + User::WaitForRequest( status ); + + LOGIT2("GetBearerSupportInfo: pckt service ntwrk reg status: %d <%d>", nwRegStatus, status.Int()) + if ( KErrNone == status.Int() && + nwRegStatus != RPacketService::ENotRegisteredNotSearching && + nwRegStatus != RPacketService::ENotRegisteredSearching && + nwRegStatus != RPacketService::ERegistrationDenied && + nwRegStatus != RPacketService::ENotRegisteredAndNotAvailable ) + { + // Query the TSY for the attach mode + RPacketService::TAttachMode attachMode( RPacketService::EAttachWhenNeeded ); + err = iPacketService.GetAttachMode( attachMode ); + + LOGIT2("GetBearerSupportInfo: pckt service attach mode: %d <%d>", attachMode, err) + // Query packet network status (but only if the TSY is set to attach when possible) + if ( KErrNone == err && attachMode == RPacketService::EAttachWhenPossible ) + { + RPacketService::TStatus pcktStatus( RPacketService::EStatusUnattached ); + err = iPacketService.GetStatus( pcktStatus ); + + LOGIT2("GetBearerSupportInfo: pckt service status: %d <%d>", pcktStatus, err) + if ( KErrNone == err && pcktStatus != RPacketService::EStatusUnattached ) + { + aByCell = ETrue; + } + } + else + { + // Attach mode is 'EAttachWhenNeeded' + aByCell = ETrue; + } + } + } + + // 2. Check the PHONE'S MODE if it is known + TUint bearerId( 0 ); + err = GetBearerId( bearerId ); + + // If phone mode query failed, mode is unknown, or bearer ID equals connection ID. + if ( bearerId == 0 || bearerId == aConnectionId ) + { + // 3. Check the PHONE'S MODE CAPABILITIES + TUint32 capsPhone( 0 ); + err = iMobilePhone.GetMultimodeCaps( capsPhone ); + + LOGIT2("GetBearerSupportInfo: mobile phone mode caps: 0x%04X <%d>", capsPhone, err) + if ( KErrNone == err ) + { + if ( aConnectionId == EBearerIdGPRS && + ( capsPhone & RMobilePhone::KCapsGprsSupported ) ) + { + aByPhone = ETrue; + } + else if ( aConnectionId == EBearerIdWCDMA && + ( capsPhone & + ( RMobilePhone::KCapsWcdmaSupported | + RMobilePhone::KCapsGprsSupported ) ) ) + { + aByPhone = ETrue; + } + } + } + } + else if ( aConnectionId == EBearerIdCSD || aConnectionId == EBearerIdWcdmaCSD ) + { + LOGIT2("GetBearerSupportInfo: CSD and WcdmaCSD, dynamic caps: 0x%04X <%d>", capsDynamic, err) + + // 1. Is CSD/WcdmaCSD supported by this NETWORK CELL + if ( capsDynamic & RPacketService::KCapsRxCSCall ) + { + // Has phone registered to the network + TRequestStatus status( KErrNone ); + RMobilePhone::TMobilePhoneRegistrationStatus gsmReg( + RMobilePhone::ERegistrationUnknown ); + + iMobilePhone.GetNetworkRegistrationStatus( status, gsmReg ); + User::WaitForRequest( status ); + + LOGIT2("GetBearerSupportInfo: mobile phone reg status: %d <%d>", gsmReg, status.Int()) + if ( KErrNone == status.Int() ) + { + if ( gsmReg == RMobilePhone::ERegisteredBusy || + gsmReg == RMobilePhone::ERegisteredOnHomeNetwork || + gsmReg == RMobilePhone::ERegisteredRoaming ) + { + aByCell = ETrue; + } + } + } + + // 2. Check the PHONE'S MODE if it is known + TUint bearerId( 0 ); + err = GetBearerId( bearerId, ETrue ); + + // If phone mode query failed, mode is unknown, or bearer ID equals connection ID. + if ( bearerId == 0 || bearerId == aConnectionId ) + { + // 3. Check the PHONE'S CAPABILITIES + err = iTelServer.IsSupportedByModule( + KMmTsyModuleName, + KETelFuncMobileDataCall, + aByPhone ); + } + } + else + { + LOGIT1("GetBearerSupportInfo: invalid connection id: %d", aConnectionId) + err = KErrArgument; + } + + LOGIT2("GetBearerSupportInfo: by cell: %d, by phone: %d", aByCell, aByPhone) + LOGEXITFN1("CConnMonIAP::GetBearerSupportInfo()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::GetBearerId +// Gets the bearer ID matching the phone's current mode. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetBearerId( TUint& aBearerId, TBool aCsd ) const + { + aBearerId = 0; + RMobilePhone::TMobilePhoneNetworkMode mode; + TInt err = iMobilePhone.GetCurrentMode( mode ); + // If GetCurrentMode() failed for any reason, aBearerId will be 0. + + LOGIT2("CConnMonIAP::GetBearerId(): current phone mode %d <%d>", mode, err) + if ( err == KErrNone ) + { + switch ( mode ) + { + case RMobilePhone::ENetworkModeWcdma: + if ( aCsd ) + { + aBearerId = EBearerIdWcdmaCSD; + } + else + { + aBearerId = EBearerIdWCDMA; + } + break; + + case RMobilePhone::ENetworkModeGsm: + case RMobilePhone::ENetworkModeUnknown: // Emulator default + if ( aCsd ) + { + aBearerId = EBearerIdCSD; + } + else + { + aBearerId = EBearerIdGPRS; + } + break; + + case RMobilePhone::ENetworkModeCdma2000: + aBearerId = EBearerIdCDMA2000; + break; + + // ENetworkModeUnregistered + // ENetworkModeAmps + // ENetworkModeCdma95 + // ENetworkModeTdcdma + default: + break; + } + } + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::Reconnect +// A new connection has been established by reconnecting to an old connection. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::Reconnect( TUint& aConnectionId ) + { + LOGENTRFN("CConnMonIAP::Reconnect()") + TInt err( KErrNone ); + + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + //return KErrNotFound; + err = KErrNotFound; + } + else + { + // Prevent ConnDown notifier from being deleted + // It will destroy itself later in reconnect case. + iConnInfos[index].iConnDownNotifier = 0; + TBearerInfo bearerInfo( EBearerInfoUnknown, EFalse ); + + TConnInfo connInfo( iConnInfos[index].iIapId, iConnInfos[index].iNetId, 0, 0, bearerInfo ); + + // AddConnectionL will remove the old connection + TInt err2( KErrNone ); + TRAP( err2, ( err = AddConnectionL( connInfo ) ) ); + if ( ( err2 != KErrNone ) || ( err != KErrNone ) ) + { + err = KErrUnknown; + } + else + { + aConnectionId = connInfo.iConnectionId; + } + } + + LOGEXITFN1("CConnMonIAP::Reconnect()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::WlanSupportCheck +// +// Returns KErrNone if the given connection ID is EBearerIdWLAN, or belongs to +// an active connection where bearer has been marked as EBearerIdWLAN. +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::WlanSupportCheck( const TUint& aConnectionId ) + { + LOGENTRFN("CConnMonIAP::WlanSupportCheck()") + TInt ret( KErrNotSupported ); + + // Check if WLAN is supported at all + if ( !iWlanSupport ) + { + LOGIT("WlanSupportCheck: no WLAN support") + ret = KErrNotSupported; + } + else + { + if ( EBearerIdWLAN == aConnectionId ) + { + ret = KErrNone; + } + else + { + // Find connection matching the given ID + TInt index = Index( aConnectionId ); + LOGIT2("WlanSupportCheck: checking connection id %d, index %d ", aConnectionId, index) + if ( index < 0 ) + { + ret = KErrArgument; + } + else + { + // Connection found, check if bearer is EBearerWLAN + if ( EBearerWLAN == iConnInfos[index].iBearer ) + { + ret = KErrNone; + } + else + { + LOGIT1("WlanSupportCheck: connection bearer %d is not WLAN", iConnInfos[index].iBearer) + ret = KErrArgument; + } + } + } + } + + LOGEXITFN1("CConnMonIAP::WlanSupportCheck()", ret) + return ret; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::AppendAvailableWLANIaps +// Gets available WLAN IAPs from WLAN engine. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::AppendAvailableWLANIaps( RArray& aIdArray ) + { + //LOGENTRFN("CConnMonIAP::AppendAvailableWLANIaps()") + TInt err( KErrNone ); + + if ( !iWlanSupport ) + { + LOGIT("AppendAvailableWLANIaps: No WLAN support") + err = KErrNotSupported; + } + else + { + err = iWlanSupport->AppendAvailableIaps( aIdArray ); + } + + //LOGEXITFN1("CConnMonIAP::AppendAvailableWLANIaps()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::AppendAvailableWLANIapsBySsid +// Gets available WLAN IAPs from CommsDat, matching with current WLAN connection SSID. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::AppendAvailableWLANIapsBySsid( RArray& aIdArray ) + { + //LOGENTRFN("CConnMonIAP::AppendAvailableWLANIapsBySsid()") + TInt err( KErrNone ); + + if ( !iWlanSupport ) + { + LOGIT("AppendAvailableWLANIapsBySsid: No WLAN support") + err = KErrNotSupported; + } + else + { + TRAPD( err2, err = iWlanSupport->AppendAvailableIapsBySsidL( aIdArray ) ); + if ( err2 != KErrNone ) + { + LOGIT1("AppendAvailableWLANIapsBySsid: error, LEAVE <%d> from AppendAvailableIapsBySsidL()", err2) + err = err2; + } + } + + //LOGEXITFN1("CConnMonIAP::AppendAvailableWLANIapsBySsid()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::EnableWlanScan +// Enables WLAN scan for the next iap availability query. +// ----------------------------------------------------------------------------------- +// +void CConnMonIAP::EnableWlanScan() + { + if ( iWlanSupport ) + { + iWlanSupport->EnableWlanScan(); + } + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::DtmStateChanged +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::DtmStateChanged() + { + LOGENTRFN("CConnMonIAP::DtmStateChanged()") + + TEventInfo eventInfo; + eventInfo.Reset(); + + // When not in dual mode and call is active, gprs and wcdma bearers are unavailable + // Note that even the WCDMA can be unavailable, if the phone doesn't support DTM + if ( iDualTransferModeNotifier && !iDualTransferModeNotifier->IsInDualMode() && + iTelephonyNotifier && iTelephonyNotifier->IsCallActive() ) + { + LOGIT("SERVER: DtmStateChanged: Packet data UNAVAILABLE (2G&3G), no DTM and call is active") + eventInfo.iEventType = EConnMonPacketDataUnavailable; + + // Send event to all clients that are listening for bearer EBearerIdGPRS + LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (GPRS), no DTM and call is active") + eventInfo.iConnectionId = EBearerIdGPRS; + iServer->EventQueue()->Add( eventInfo ); // Create bearer availability event if needed + + // Send event to all clients that are listening for bearer EBearerIdWCDMA + LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (WCDMA), no DTM and call is active") + eventInfo.iConnectionId = EBearerIdWCDMA; + iServer->EventQueue()->Add( eventInfo ); + } + else + { + TBool byPhone( EFalse ); + TBool byCell( EFalse ); + + // Lets check if GPRS bearer is available at all + TInt ret = GetBearerSupportInfo( EBearerIdGPRS, byCell, byPhone ); + LOGIT2("Bearer support (GPRS): byCell %d, byPhone %d", byCell, byPhone) + if ( ret != KErrNone ) + { + LOGIT1("SERVER: DtmStateChanged: GetBearerSupportInfo (GPRS) returned error <%d>", ret) + return; // No event on error + } + + eventInfo.iConnectionId = EBearerIdGPRS; + if ( byCell && byPhone ) + { + LOGIT("SERVER: EVENT -> Packet data AVAILABLE (GPRS), DTM or no call is active") + eventInfo.iEventType = EConnMonPacketDataAvailable; + } + else + { + LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (GPRS), no GPRS bearer") + eventInfo.iEventType = EConnMonPacketDataUnavailable; + } + // Send event to all clients that are listening for bearer EBearerIdGPRS + iServer->EventQueue()->Add( eventInfo ); + + + // Same for WCDMA as for GPRS above + ret = GetBearerSupportInfo( EBearerIdWCDMA, byCell, byPhone ); + LOGIT2("Bearer support (WCDMA): byCell %d, byPhone %d", byCell, byPhone) + if ( ret != KErrNone ) + { + LOGIT1("SERVER: DtmStateChanged: GetBearerSupportInfo (WCDMA) returned error <%d>", ret) + return; // No event on error + } + + eventInfo.iConnectionId = EBearerIdWCDMA; + if ( byCell && byPhone ) + { + LOGIT("SERVER: EVENT -> Packet data AVAILABLE (WCDMA), DTM or no call is active") + eventInfo.iEventType = EConnMonPacketDataAvailable; + } + else + { + LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (WCDMA), no WCDMA bearer") + eventInfo.iEventType = EConnMonPacketDataUnavailable; + } + // Send event to all clients that are listening for bearer EBearerIdWCDMA + iServer->EventQueue()->Add( eventInfo ); + } + + LOGEXITFN("CConnMonIAP::DtmStateChanged()") + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::PhoneLineStatusChange +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::PhoneLineStatusChange() + { + LOGENTRFN("CConnMonIAP::PhoneLineStatusChange()") + + // At this time the implementation would be identical + // to DtmStateChanged so we just call it + DtmStateChanged(); + + LOGEXITFN("CConnMonIAP::PhoneLineStatusChange()") + } + + +// PRIVATE METHODS BELOW + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::OpenAndAttachTo +// Opens and attaches an RConnection instance. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::OpenAndAttachTo( TConnInfo& aConnInfo ) + { + //LOGENTRFN("CConnMonIAP::OpenAndAttachTo()") + TInt err( KErrNone ); + TConnectionInfo info; + TPckg pckgInfo( info ); + + // Leave left out intentionally, check for NULL instead + aConnInfo.iConnAttach = new RConnection(); // No (ELeave) + if ( !aConnInfo.iConnAttach ) + { + err = KErrNoMemory; + } + if ( KErrNone == err ) + { + err = aConnInfo.iConnAttach->Open( iSocketServer, KAfInet ); + } + + if ( KErrNone == err ) + { + info.iIapId = aConnInfo.iIapId; + info.iNetId = aConnInfo.iNetId; + + err = aConnInfo.iConnAttach->Attach( pckgInfo, RConnection::EAttachTypeMonitor ); + if ( err != KErrNone ) + { + aConnInfo.iConnAttach->Close(); + delete aConnInfo.iConnAttach; + } + } + + //LOGEXITFN1("CConnMonIAP::OpenAndAttachTo()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::StopConnection +// Closes a connection. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::StopConnection( const TInt aIndex ) + { + LOGENTRFN("CConnMonIAP::StopConnection()") + TInt err( KErrNone ); + + if ( ( aIndex < 0 ) || ( aIndex >= iConnInfos.Count() ) ) + { + LOGEXITFN1("CConnMonIAP::StopConnection()", KErrArgument) + return KErrArgument; + } + + if ( iConnInfos[aIndex].iBearer < EBearerExternalCSD ) + { + // Stop an internal connection + RConnection connection; + TConnectionInfo info; + + // Cancel data volume and activity notifiers before stopping + if ( iConnInfos[aIndex].iDLDataNotifier != 0 ) + { + iConnInfos[aIndex].iDLDataNotifier->Cancel(); + } + if ( iConnInfos[aIndex].iULDataNotifier != 0 ) + { + iConnInfos[aIndex].iULDataNotifier->Cancel(); + } + if ( iConnInfos[aIndex].iDataVolumeAO != 0 ) + { + iConnInfos[aIndex].iDataVolumeAO->Cancel(); + } + if ( iConnInfos[aIndex].iActivityNotifier != 0 ) + { + iConnInfos[aIndex].iActivityNotifier->Cancel(); + } + + // RConnection object with EAttachTypeNormal is needed for stopping + err = connection.Open( iSocketServer, KAfInet ); + if ( KErrNone == err ) + { + info.iIapId = iConnInfos[aIndex].iIapId; + info.iNetId = iConnInfos[aIndex].iNetId; + + err = connection.Attach( TPckg( info ), + RConnection::EAttachTypeNormal ); + if ( KErrNone == err ) + { + err = connection.Stop( RConnection::EStopAuthoritative ); + if ( KErrNone == err ) + { + // Stop notifications, delete connection settings and remove from the table + // If conn up/down notifier is active, let the event remove connection later. + if ( !iConnUpDownNotifier || !iConnUpDownNotifier->IsActive() ) + { + RemoveConnection( iConnInfos[aIndex] ); + } + } + else + { + LOGIT1("StopConnection: RConnection::Stop() failed <%d>", err) + } + } + else + { + LOGIT1("StopConnection: RConnection::Attach() failed <%d>", err) + } + connection.Close(); + } + else + { + LOGIT1("StopConnection: RConnection::Open() failed <%d>", err) + } + } + + else if ( iConnInfos[aIndex].iBearer == EBearerExternalGPRS || + iConnInfos[aIndex].iBearer == EBearerExternalEdgeGPRS || + iConnInfos[aIndex].iBearer == EBearerExternalWCDMA || + iConnInfos[aIndex].iBearer == EBearerExternalCDMA2000 || + ( !iConnInfos[aIndex].iBearerInfo.iInternal && + ( iConnInfos[aIndex].iBearerInfo.iBearer == EBearerInfoHSDPA || + iConnInfos[aIndex].iBearerInfo.iBearer == EBearerInfoHSUPA || + iConnInfos[aIndex].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) + { + // EXTERNAL PSD + if ( iPsdFax ) + { + err = iPsdFax->Stop( iConnInfos[aIndex].iConnectionId ); + } + else + { + err = KErrNotFound; + } + } + + else if ( iConnInfos[aIndex].iBearer == EBearerExternalCSD || + iConnInfos[aIndex].iBearer == EBearerExternalHSCSD || + iConnInfos[aIndex].iBearer == EBearerExternalWcdmaCSD ) + { + // EXTERNAL CSD + if ( iCsdFax ) + { + err = iCsdFax->Stop(); + } + else + { + err = KErrNotFound; + } + } + else + { + err = KErrNotSupported; + } + + LOGEXITFN1("CConnMonIAP::StopConnection()", err) + return err; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::AddConnNotificationsL +// Adds connection specific event watchers (connection status, data volume, activity). +// ----------------------------------------------------------------------------------- +// +void CConnMonIAP::AddConnNotificationsL( const TInt& aIndex ) + { + LOGENTRFN("CConnMonIAP::AddConnNotificationsL()") + + if ( iConnInfos[aIndex].iBearer < EBearerExternalCSD ) + { + // INTERNAL CONNECTIONS + TInt connectionStatus( 0 ); + GetConnectionStatus( aIndex, connectionStatus ); + + // ---------------------- + // Connection Status + // ---------------------- + if ( iConnInfos[aIndex].iProgressNotifier == 0 ) + { + TInt subConnectionId( 0 ); + + // Create an active object and add it to scheduler + iConnInfos[aIndex].iProgressNotifier = new( ELeave ) CProgressNotifier( + iServer, + iConnInfos[aIndex].iConnAttach, + iConnInfos[aIndex].iConnectionId, + subConnectionId ); + + iConnInfos[aIndex].iProgressNotifier->Construct(); + + if ( iConnUpDownNotifier->IsActive() ) + { + // Client is starting notifications. Filter old status events. + iConnInfos[aIndex].iProgressNotifier->Receive( connectionStatus ); + } + else + { + // Event is starting notifification. No filtering is needed. + iConnInfos[aIndex].iProgressNotifier->Receive(); + } + } + + // ------------------------- + // Amount of Downlink data + // ------------------------- + if ( iConnInfos[aIndex].iDLDataNotifier == 0 ) + { + TInt subConnectionId( 0 ); + + // Create an active object and add it to scheduler + iConnInfos[aIndex].iDLDataNotifier = new( ELeave ) CDataNotifier( + iServer, + iConnInfos[aIndex].iConnAttach, + iConnInfos[aIndex].iConnectionId, + subConnectionId, + CDataNotifier::EDownlink); + + iConnInfos[aIndex].iDLDataNotifier->Construct(); + + if ( ( connectionStatus == KLinkLayerOpen ) || + ( connectionStatus == KPsdSuspended ) ) + { + iConnInfos[aIndex].iDLDataNotifier->Receive(); + } + } + + // ------------------------- + // Amount of Uplink data + // ------------------------- + if ( iConnInfos[aIndex].iULDataNotifier == 0 ) + { + TInt subConnectionId( 0 ); + + // Create an active object and add it to scheduler + iConnInfos[aIndex].iULDataNotifier = new( ELeave ) CDataNotifier( + iServer, + iConnInfos[aIndex].iConnAttach, + iConnInfos[aIndex].iConnectionId, + subConnectionId, + CDataNotifier::EUplink); + + iConnInfos[aIndex].iULDataNotifier->Construct(); + + if ( ( connectionStatus == KLinkLayerOpen ) || + ( connectionStatus == KPsdSuspended ) ) + { + iConnInfos[aIndex].iULDataNotifier->Receive(); + } + } + + // --------------------------------------- + // Connection down event with data volumes + // --------------------------------------- + if ( iConnInfos[aIndex].iConnDownNotifier == 0 ) + { + TInt subConnectionId( 0 ); + + // Create an active object and add it to scheduler + iConnInfos[aIndex].iConnDownNotifier = new( ELeave ) CSubConnUpDownNotifier( + iServer, + iConnInfos[aIndex].iConnAttach, + iConnInfos[aIndex].iConnectionId, + subConnectionId ); + + iConnInfos[aIndex].iConnDownNotifier->Construct(); + + // Receiving will start only when connection status reaches KLinkLayerOpen + if ( ( connectionStatus == KLinkLayerOpen ) || + ( connectionStatus == KPsdSuspended ) ) + { + iConnInfos[aIndex].iConnDownNotifier->Receive(); + } + } + + // ---------------------- + // Connection Activity + // ---------------------- + if ( iConnInfos[aIndex].iActivityNotifier == 0 ) + { + // To update internal table fast at the first time + if ( ( connectionStatus == KLinkLayerOpen ) || + ( connectionStatus == KPsdSuspended ) ) + { + GetActivityOneShotL( aIndex ); + } + } + else + { + if ( !iConnInfos[aIndex].iActivityNotifier->IsActive() ) + { + iConnInfos[aIndex].iActivityNotifier->Receive( iConnInfos[aIndex].iActivity ); + } + } + + // ---------------------- + // Connection Bearer + // ---------------------- + if ( iConnInfos[aIndex].iBearerNotifier == 0 ) + { + // Create an active object and add it to scheduler + iConnInfos[aIndex].iBearerNotifier = CConnMonBearerNotifier::NewL( + iServer, + iMobilePhone, + iConnInfos[aIndex].iConnectionId ); + + // Receiving will start only when connection status reaches KLinkLayerOpen + if ( ( connectionStatus == KLinkLayerOpen ) || + ( connectionStatus == KPsdSuspended ) ) + { + iConnInfos[aIndex].iBearerNotifier->Listen(); + } + } + + // Note. iDataVolumeAO is created when client asks data volume info + } + LOGEXITFN("CConnMonIAP::AddConnNotificationsL()") + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::DeleteConnNotifications +// Deletes event watchers owned by a connection +// ----------------------------------------------------------------------------------- +// +void CConnMonIAP::DeleteConnNotifications( const TInt& aIndex ) + { + LOGENTRFN("CConnMonIAP::DeleteConnNotifications()") + if ( iConnInfos[ aIndex ].iBearer < EBearerExternalCSD ) + { + if ( iConnInfos[ aIndex ].iProgressNotifier ) + { + iConnInfos[ aIndex ].iProgressNotifier->Cancel(); + delete iConnInfos[ aIndex ].iProgressNotifier; + iConnInfos[ aIndex ].iProgressNotifier = NULL; + } + + if ( iConnInfos[ aIndex ].iDLDataNotifier ) + { + iConnInfos[ aIndex ].iDLDataNotifier->Cancel(); + delete iConnInfos[ aIndex ].iDLDataNotifier; + iConnInfos[ aIndex ].iDLDataNotifier = NULL; + } + + if ( iConnInfos[ aIndex ].iULDataNotifier ) + { + iConnInfos[ aIndex ].iULDataNotifier->Cancel(); + delete iConnInfos[ aIndex ].iULDataNotifier; + iConnInfos[ aIndex ].iULDataNotifier = NULL; + } + + if ( iConnInfos[ aIndex ].iDataVolumeAO ) + { + iConnInfos[ aIndex ].iDataVolumeAO->Cancel(); + delete iConnInfos[ aIndex ].iDataVolumeAO; + iConnInfos[ aIndex ].iDataVolumeAO = NULL; + } + + if ( iConnInfos[ aIndex ].iConnDownNotifier ) + { + iConnInfos[ aIndex ].iConnDownNotifier->Cancel(); + delete iConnInfos[ aIndex ].iConnDownNotifier; + iConnInfos[ aIndex ].iConnDownNotifier = NULL; + } + + if ( iConnInfos[ aIndex ].iActivityNotifier ) + { + iConnInfos[ aIndex ].iActivityNotifier->Cancel(); + delete iConnInfos[ aIndex ].iActivityNotifier; + iConnInfos[ aIndex ].iActivityNotifier = NULL; + } + + if ( iConnInfos[ aIndex ].iBearerNotifier ) + { + iConnInfos[ aIndex ].iBearerNotifier->CancelListen(); + delete iConnInfos[ aIndex ].iBearerNotifier; + iConnInfos[ aIndex ].iBearerNotifier = NULL; + } + } + LOGEXITFN("CConnMonIAP::DeleteConnNotifications()") + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::DeleteNotifications +// Deletes all the event watchers from the system (expect connection up/down events) +// ----------------------------------------------------------------------------------- +// +void CConnMonIAP::DeleteNotifications() + { + if( iTelephonyNotifier ) + { + delete iTelephonyNotifier; + iTelephonyNotifier = NULL; + } + + if( iDualTransferModeNotifier ) + { + delete iDualTransferModeNotifier; + iDualTransferModeNotifier = NULL; + } + + if ( iPsdNetwStatusNotifier ) + { + // Cancel any outstanding requests + iPsdNetwStatusNotifier->Cancel(); + delete iPsdNetwStatusNotifier; + iPsdNetwStatusNotifier = NULL; + } + + if ( iNetwRegistrationNotifier ) + { + // Cancel any outstanding requests + iNetwRegistrationNotifier->Cancel(); + delete iNetwRegistrationNotifier; + iNetwRegistrationNotifier = NULL; + } + + if ( iEdgeNotifier ) + { + // Cancel any outstanding requests + iEdgeNotifier->Cancel(); + delete iEdgeNotifier; + iEdgeNotifier = NULL; + } + + if ( iWcdmaNotifier ) + { + iWcdmaNotifier->Cancel(); + delete iWcdmaNotifier; + iWcdmaNotifier = NULL; + } + + if ( iModeNotifier ) + { + // Cancel any outstanding requests + iModeNotifier->Cancel(); + delete iModeNotifier; + iModeNotifier = NULL; + } + + if ( iGSMSignalNotifier ) + { + // Cancel any outstanding requests + iGSMSignalNotifier->Cancel(); + delete iGSMSignalNotifier; + iGSMSignalNotifier = NULL; + } + + if ( iGSMBearerAvailabilityNotifier ) + { + // Cancel any outstanding requests + iGSMBearerAvailabilityNotifier->Cancel(); + delete iGSMBearerAvailabilityNotifier; + iGSMBearerAvailabilityNotifier = NULL; + } + + if ( iWlanSupport ) + { + iWlanSupport->DisableEventsToClients(); + } + + // Delete notifications owned by the connections + TInt count = iConnInfos.Count(); + for ( TInt i = 0; i < count; i++ ) + { + DeleteConnNotifications( i ); + } + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::NewConnectionId +// Returns a new unique connection id for the connection. +// ----------------------------------------------------------------------------------- +// +TUint CConnMonIAP::NewConnectionId() + { + ++iIdCounter; + + if ( iIdCounter == KMaxConnectionId ) + { + iIdCounter = 1; + } + + return iIdCounter; + } + +// ----------------------------------------------------------------------------------- +// CConnMonIAP::Index +// Finds the index of the matching object within the array. +// KErrNotFound, if no matching object can be found. +// ----------------------------------------------------------------------------------- +// +TInt CConnMonIAP::Index( const TUint& aConnectionId ) + { + TInt count = iConnInfos.Count(); + for ( TInt i = 0; i < count; i++ ) + { + if ( iConnInfos[i].iConnectionId == aConnectionId ) + { + return i; + } + } + + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetAccessPointName +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetAccessPointName( const TUint& aConnectionId, TDes& aName ) + { + LOGENTRFN("CConnMonIAP::GetAccessPointName()") + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + err = KErrNotFound; + } + else + { + // Find out access point name + TBuf settingName; + TBuf settingValue; + settingName.Copy( TPtrC( IAP ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( IAP_SERVICE_TYPE ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( + TPtrC( settingName ), + settingValue ); + if ( KErrNone == err ) + { + if ( settingValue == TPtrC( OUTGOING_WCDMA ) || + settingValue == TPtrC( INCOMING_WCDMA ) ) + { + settingName.Copy( settingValue ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( GPRS_APN ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( + TPtrC( settingName ), + aName ); + } + else + { + err = KErrNotFound; + } + } + } + + LOGEXITFN1("CConnMonIAP::GetAccessPointName()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetTelNumber +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetTelNumber( const TUint& aConnectionId, TDes& aTelNum ) + { + LOGENTRFN("CConnMonIAP::GetTelNumber()") + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + err = KErrNotFound; + } + else + { + // Find out tel. number + TBuf settingName; + TBuf settingValue; + settingName.Copy( TPtrC( IAP ) ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( IAP_SERVICE_TYPE ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( + TPtrC( settingName ), + settingValue ); + if ( KErrNone == err ) + { + if ( settingValue == TPtrC( DIAL_OUT_ISP ) || + settingValue == TPtrC( DIAL_IN_ISP ) ) + { + settingName.Copy( settingValue ); + settingName.Append( TChar( '\\' ) ); + settingName.Append( TPtrC( ISP_DEFAULT_TEL_NUM ) ); + + err = iConnInfos[index].iConnAttach->GetDesSetting( + TPtrC( settingName ), + aTelNum ); + } + else + { + err = KErrNotFound; + } + } + } + + LOGEXITFN1("CConnMonIAP::GetTelNumber()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetConnectionStatus +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetConnectionStatus( const TInt& aIndex, TInt& aConnectionStatus ) + { + //LOGENTRFN("CConnMonIAP::GetConnectionStatus()") + TInt err( KErrNone ); + TNifProgress nifProgress; + + if ( ( aIndex < 0 ) || ( aIndex >= iConnInfos.Count() ) ) + { + LOGIT1("GetConnectionStatus: invalid index value: %d", aIndex) + err = KErrArgument; + } + else + { + aConnectionStatus = 0; + err = iConnInfos[aIndex].iConnAttach->Progress( nifProgress ); + if ( KErrNone == err ) + { + aConnectionStatus = nifProgress.iStage; + LOGIT1("GetConnectionStatus: iConnAttach->Progress() status: %d", aConnectionStatus) + } + else + { + LOGIT1("GetConnectionStatus: ERROR getting progress status <%d>", err) + } + } + + //LOGEXITFN1("CConnMonIAP::GetConnectionStatus()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetPsdNetworkStatus +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetPsdNetworkStatus( TInt& aNetworkStatus ) const + { + LOGENTRFN("CConnMonIAP::GetPsdNetworkStatus()") + TInt err( KErrNone ); + + if ( iTSYLoaded && iPacketServLoaded ) + { + RPacketService::TStatus packetStatus; + err = iPacketService.GetStatus( packetStatus ); + if ( KErrNone == err ) + { + aNetworkStatus = CalculateNetworkStatus( packetStatus ); + LOGIT1("GetPsdNetworkStatus: status %d", aNetworkStatus) + } + } + else + { + aNetworkStatus = EConnMonStatusUnattached; + } + + LOGEXITFN1("CConnMonIAP::GetPsdNetworkStatus()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetNetworkRegistrationMode +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetNetworkRegistrationMode( TInt& aRegistration ) const + { + return GetNetworkRegistration( aRegistration ); + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetNetworkRegistration +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetNetworkRegistration( TInt& aRegistration ) const + { + LOGENTRFN("CConnMonIAP::GetNetworkRegistration()") + TInt err( KErrNone ); + + if ( !FeatureManager::FeatureSupported( KFeatureIdNetworkRegistration ) ) + { + LOGIT("GetNetworkRegistration: KFeatureIdNetworkRegistration not supported") + err = KErrNotSupported; + } + else + { + if ( iTSYLoaded ) + { + TRequestStatus status( KErrNone ); + RMobilePhone::TMobilePhoneRegistrationStatus registration( + RMobilePhone::ERegistrationUnknown ); + + iMobilePhone.GetNetworkRegistrationStatus( status, registration ); + User::WaitForRequest( status ); + err = status.Int(); + if ( KErrNone == err ) + { + aRegistration = CalculateNetworkRegistration( registration ); + LOGIT1("GetNetworkRegistration: registration %d", aRegistration) + } + } + else + { + aRegistration = ENetworkRegistrationNotAvailable; + } + } + + LOGEXITFN1("CConnMonIAP::GetNetworkRegistration()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetNetworkRegistration_v2 +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetNetworkRegistration_v2( TInt& aRegistration ) const + { + LOGENTRFN("CConnMonIAP::GetNetworkRegistration_v2()") + TInt err( KErrNone ); + + if ( !FeatureManager::FeatureSupported( KFeatureIdNetworkRegistration ) ) + { + LOGIT("GetNetworkRegistration_v2: KFeatureIdNetworkRegistration not supported") + err = KErrNotSupported; + } + else + { + if ( iTSYLoaded ) + { + TRequestStatus status( KErrNone ); + RMobilePhone::TMobilePhoneRegistrationStatus registration( + RMobilePhone::ERegistrationUnknown ); + + iMobilePhone.GetNetworkRegistrationStatus( status, registration ); + User::WaitForRequest( status ); + err = status.Int(); + if ( KErrNone == err ) + { + aRegistration = CalculateNetworkRegistration_v2( registration ); + LOGIT1("GetNetworkRegistration_v2: registration <%d>", aRegistration ) + } + } + else + { + aRegistration = ENetworkRegistrationExtNotAvailable; + } + } + + LOGEXITFN1("CConnMonIAP::GetNetworkRegistration_v2()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetGSMSignalStrength +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetGSMSignalStrength( TInt& aSignalStrength ) const + { + LOGENTRFN("CConnMonIAP::GetGSMSignalStrength()") + TInt err( KErrNone ); + + if ( iTSYLoaded ) + { + TRequestStatus status( KErrNone ); + TInt32 strength( 0 ); + TInt8 bar( -1 ); + + iMobilePhone.GetSignalStrength( status, strength, bar ); + User::WaitForRequest( status ); + + err = status.Int(); + if ( KErrNone == err ) + { + aSignalStrength = strength; + LOGIT1("GetGSMSignalStrength: strength %d", aSignalStrength) + } + } + else + { + err = KErrNotSupported; + } + + LOGEXITFN1("CConnMonIAP::GetGSMSignalStrength()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetProtocolTypeL +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetProtocolTypeL( const TUint& aConnectionId, TInt& aProtocolType ) + { + LOGENTRFN("CConnMonIAP::GetProtocolTypeL()") + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + if ( index < 0 ) + { + LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", KErrNotFound) + return KErrNotFound; + } + + aProtocolType = EProtocolTypeUnknown; + + if ( iTSYLoaded && iPacketServLoaded ) + { + // Get AP name for the connection + TBuf apName; + + err = GetAccessPointName( iConnInfos[index].iConnectionId, apName ); + + if ( KErrNotFound == err ) + { + LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err) + return err; + } + + // Enumerate all PDP contexts + TRequestStatus status( KErrNone ); + TInt contextCount( 0 ); + TInt maxContextCount( 0 ); + + iPacketService.EnumerateContexts( status, contextCount, maxContextCount ); + User::WaitForRequest( status ); + + err = status.Int(); + if ( err != KErrNone ) + { + LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err) + return err; + } + + RPacketService::TContextInfo contextInfo; + RPacketContext context; + CleanupClosePushL( context ); + + // Find PDP contexts matching the given connectionId + for ( TInt i = 0; ( i < contextCount ) && ( aProtocolType != EProtocolTypeIP ); i++ ) + { + iPacketService.GetContextInfo( status, i, contextInfo ); //iName, iStatus + User::WaitForRequest( status ); + + err = status.Int(); + if ( err != KErrNone ) + { + LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err) + return err; + } + + err = context.OpenExistingContext( iPacketService, contextInfo.iName ); + if ( err != KErrNone ) + { + LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err) + return err; + } + + RPacketContext::TContextConfigGPRS* getParams; + getParams = new( ELeave ) RPacketContext::TContextConfigGPRS(); + TPckg getContextConfigPckg( *getParams ); + + context.GetConfig( status, getContextConfigPckg ); + User::WaitForRequest( status ); + + err = status.Int(); + if ( KErrNone == err ) + { + TInt ret = CompareAccessPointNames( apName, getParams->iAccessPointName ); + + if ( ret == 0 ) + { + // PDP context matching the IAP connection found + if ( getParams->iPdpType == RPacketContext::EPdpTypeIPv4 ) + { + if ( aProtocolType == EProtocolTypeIPv6 ) + { + aProtocolType = EProtocolTypeIP; // Both 4 & 6 + } + else + { + aProtocolType = EProtocolTypeIPv4; + } + } + else if ( getParams->iPdpType == RPacketContext::EPdpTypeIPv6 ) + { + if ( aProtocolType == EProtocolTypeIPv4 ) + { + aProtocolType = EProtocolTypeIP; // Both 4 & 6 + } + else + { + aProtocolType = EProtocolTypeIPv6; + } + } + else + { + aProtocolType = EProtocolTypeUnknown; + } + } + } + + delete getParams; + context.Close(); + + if ( err != KErrNone ) + { + break; + } + } // for + CleanupStack::PopAndDestroy( &context ); + } // if + + LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err) + return err; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetActivityOneShotL +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::GetActivityOneShotL( const TInt& aIndex ) + { + if ( iConnInfos[aIndex].iActivityNotifier == 0 ) + { + iConnInfos[aIndex].iActivityNotifier = new( ELeave ) CActivityNotifier( + iServer, + iConnInfos[aIndex].iConnAttach, + iConnInfos[aIndex].iConnectionId, + 0 ); + iConnInfos[aIndex].iActivityNotifier->Construct(); + } + + if ( !iConnInfos[aIndex].iActivityNotifier->IsActive() ) + { + iConnInfos[aIndex].iActivityNotifier->ReceiveOne( + iConnInfos[aIndex].iActivity ); + + // This AO will cancel the activity notifier after one second in case it has not completed. + // AO will destroy itself in RunL. + CTimerAO* timerAO = new( ELeave ) CTimerAO( + iServer, + iConnInfos[aIndex].iConnectionId, + iConnInfos[aIndex].iActivity ); + + CleanupStack::PushL( timerAO ); + timerAO->ConstructL(); + CleanupStack::Pop( timerAO ); + + timerAO->Start(); + } + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::GetBearerFromETel +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::GetBearerFromETel( + const TDes& aNumber, + TInt& aBearer, + TBearerInfo& aBearerInfo ) + { + TInt ret( KErrNone ); + TInt countCalls( 0 ); + RLine line; + RMobileCall call; + + // Get phone info + RTelServer::TPhoneInfo phoneInfo; + ret = iTelServer.GetPhoneInfo( 0, phoneInfo ); + if ( KErrNone != ret ) + { + return ret; + } + + ret = line.Open( iMobilePhone, KMmTsyDataLineName ); + if ( KErrNone != ret ) + { + return ret; + } + + // Enumerate calls on data line + ret = line.EnumerateCall( countCalls ); + if ( KErrNone != ret ) + { + line.Close(); + return ret; + } + + // Get call info + for ( TInt j = 0; j < countCalls; j++ ) + { + RLine::TCallInfo callInfo; + + ret = line.GetCallInfo( j, callInfo ); + if ( KErrNone != ret ) + { + line.Close(); + return ret; + } + + if ( callInfo.iStatus != RCall::EStatusIdle ) + { + TName callName; + + callName.Copy( phoneInfo.iName ); + callName.Append( KDoubleColon ); + callName.Append( KMmTsyDataLineName ); + callName.Append( KDoubleColon ); + callName.Append( callInfo.iCallName ); + + ret = call.OpenExistingCall( iTelServer, callName ); + if ( KErrNone != ret ) + { + line.Close(); + return ret; + } + + RMobileCall::TMobileCallInfoV1 info; + RMobileCall::TMobileCallInfoV1Pckg infoPckg( info ); + + ret = call.GetMobileCallInfo( infoPckg ); + if ( KErrNone == ret ) + { + if ( infoPckg().iRemoteParty.iRemoteNumber.iTelNumber.Length() > 0 ) + { + ret = aNumber.Compare( infoPckg().iRemoteParty.iRemoteNumber.iTelNumber ); + } + else if ( infoPckg().iDialledParty.iTelNumber.Length() > 0 ) + { + ret = aNumber.Compare( infoPckg().iDialledParty.iTelNumber ); + } + else + { + ret = KErrNotFound; + } + + if ( ret == 0 ) + { + aBearer = EBearerCSD; + aBearerInfo.iBearer = EBearerInfoCSD; + aBearerInfo.iInternal = ETrue; + + RMobileCall::TMobileCallHscsdInfoV1 hscsdInfo; + RMobileCall::TMobileCallHscsdInfoV1Pckg hscsdInfoPckg( hscsdInfo ); + + ret = call.GetCurrentHscsdInfo( hscsdInfoPckg ); + if ( KErrNone == ret ) + { + if ( hscsdInfo.iAiur != RMobileCall::EAiurBpsUnspecified ) + { + aBearer = EBearerHSCSD; + aBearerInfo.iBearer = EBearerInfoHSCSD; + } + } + call.Close(); + line.Close(); + return KErrNone; + } + } + call.Close(); + } + } // for + line.Close(); + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::CompareAccessPointNames +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::CompareAccessPointNames( + const TDesC& aNameFromCommDB, + const TDesC& aNameFromETel ) const + { + return ( aNameFromETel.Compare( aNameFromCommDB ) ); + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::CompareAccessPointNames +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::CompareAccessPointNames( + const TDesC& aNameFromCommDB, + const TDesC8& aNameFromETel ) const + { + TBuf tempBuffer; + + CnvUtfConverter::ConvertToUnicodeFromUtf8( tempBuffer, aNameFromETel ); + + return( tempBuffer.Compare( aNameFromCommDB ) ); + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::SendConnectionEvents +// ----------------------------------------------------------------------------- +// +void CConnMonIAP::SendConnectionEvents( TConnMonBearerInfo& /*aBearerinfo*/ ) + { + if ( iConnInfos.Count() > 0 ) + { + for ( TInt i = 0; i < iConnInfos.Count(); i++ ) + { + if ( iConnInfos[i].iBearerNotifier ) + { + iConnInfos[i].iBearerNotifier->SendBearerInfoEvent(); + iConnInfos[i].iBearerNotifier->SendBearerGroupEvent(); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CConnMonIAP::LastProgressError +// ----------------------------------------------------------------------------- +// +TInt CConnMonIAP::LastProgressError( + const TUint& aConnectionId, + TNifProgress& aProgress ) + { + TInt err( KErrNone ); + + // Find connection matching the given Id + TInt index = Index( aConnectionId ); + + if ( index < 0 ) + { + return KErrNotFound; + } + + err = iConnInfos[index].iConnAttach->LastProgressError( aProgress ); + + LOGIT3("iConnection->Progress() ret <%d> stage %d error <%d>", err, aProgress.iStage, aProgress.iError) + return err; + } + +// --------------------------------------------------------------------------- +// CConnMonIAP::WlanRssGoodEnough +// --------------------------------------------------------------------------- +// +TBool CConnMonIAP::WlanRssGoodEnough() + { + //LOGENTRFN("CConnMonIAP::WlanRssGoodEnough()") + TBool value( EFalse ); + + if ( !iWlanSupport ) + { + LOGIT("WlanRssGoodEnough: No WLAN support") + value = EFalse; + } + else + { + value = iWlanSupport->WlanRssGoodEnough(); + } + + //LOGEXITFN1("CConnMonIAP::WlanRssGoodEnough()", value) + return value; + } + +// --------------------------------------------------------------------------- +// CConnMonIAP::DiscoverBearerId +// --------------------------------------------------------------------------- +// +TInt CConnMonIAP::BearerIdForBearerAvailability( + const TUint& aConnId, + TUint& aBearerId ) + { + LOGENTRFN("CConnMonIAP::BearerIdForBearerAvailability()") + TInt err( KErrNone ); + + TInt index = Index( aConnId ); + if ( index < 0 ) + { + // Bearer specific connection id given as attribute + switch ( aConnId ) + { + case EBearerIdWLAN: aBearerId = EBearerIdWLAN; break; + case EBearerIdGPRS: aBearerId = EBearerIdGPRS; break; + case EBearerIdWCDMA: aBearerId = EBearerIdWCDMA; break; + case EBearerIdCSD: aBearerId = EBearerIdCSD; break; + case EBearerIdWcdmaCSD: aBearerId = EBearerIdWcdmaCSD; break; + // Let session send this request to the plugin + case EBearerIdLAN: err = KErrCancel; break; + default: err = KErrNotFound; break; + } + } + else + { + // Valid connection id given as attribute + switch ( iConnInfos[index].iBearer ) + { + case EBearerWLAN: aBearerId = EBearerIdWLAN; break; + case EBearerGPRS: + case EBearerEdgeGPRS: + case EBearerExternalGPRS: + case EBearerExternalEdgeGPRS: aBearerId = EBearerIdGPRS; break; + case EBearerWCDMA: + case EBearerExternalWCDMA: aBearerId = EBearerIdWCDMA; break; + case EBearerCSD: + case EBearerHSCSD: + case EBearerExternalCSD: + case EBearerExternalHSCSD: aBearerId = EBearerIdCSD; break; + case EBearerWcdmaCSD: + case EBearerExternalWcdmaCSD: aBearerId = EBearerIdWcdmaCSD; break; + // Let session send this request to the plugin + case EBearerLAN: err = KErrCancel; break; + default: err = KErrNotSupported; break; + } + } + + LOGEXITFN1("CConnMonIAP::BearerIdForBearerAvailability()", err) + return err; + } + +// End-of-file