--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/connectionmonitoring/connmon/connectionmonitor/src/ConnMonSess.cpp Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,2657 @@
+/*
+* 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: Connection Monitor session.
+*
+*/
+
+#include <featmgr.h>
+#include <etelmm.h>
+#include <rconnmon.h>
+
+#include "ConnMonSess.h"
+#include "ConnMonServ.h"
+#include "ConnMonIAP.h"
+#include "ConnMonDef.h"
+#include "CEventQueue.h"
+#include "CIapSupport.h"
+#include "CUiDialogAO.h"
+#include "ConnMonUtils.h"
+#include "ConnMonAvailabilityManager.h"
+#include "ConnMonBearerGroupManager.h"
+#include "connmonwlannetwork.h"
+#include "CPlugin.h"
+#include "log.h"
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TConnSettings::TConnSettings
+// -----------------------------------------------------------------------------
+//
+TConnSettings::TConnSettings(
+ TUint aActivityTimeThreshold,
+ TUint aDLDataThreshold,
+ TUint aULDataThreshold )
+ :
+ iActivityTimeThreshold( aActivityTimeThreshold ),
+ iDLDataThreshold( aDLDataThreshold ),
+ iULDataThreshold( aULDataThreshold )
+ {
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TConnRequest::TConnRequest
+// -----------------------------------------------------------------------------
+//
+TConnRequest::TConnRequest( TUint8 aType, const RMessage2 aMessage )
+ :
+ iType( aType ),
+ iMessage( aMessage )
+ {
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TConnParams::TConnParams
+// -----------------------------------------------------------------------------
+//
+TConnParams::TConnParams( TUint aConnectionId )
+ :
+ iConnectionId( aConnectionId ),
+ iSettings( 0, 0, 0 )
+ {
+ iRequests.Reset();
+ }
+
+
+// -----------------------------------------------------------------------------
+// TConnParams::MatchId
+// Finds TConnParams item matching by connection Id.
+// -----------------------------------------------------------------------------
+//
+TBool TConnParams::MatchId( const TConnParams& aFirst, const TConnParams& aSecond )
+ {
+ if ( aFirst.iConnectionId == aSecond.iConnectionId )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CConnMonSession
+// -----------------------------------------------------------------------------
+//
+CConnMonSession::CConnMonSession( CConnMonServer* aServer )
+ :
+ CSession2(),
+ iCmServer( aServer )
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::ConstructL()
+ {
+ //LOGENTRFN("CConnMonSession::ConstructL()")
+
+ iListening = EFalse;
+ iEnumConnInfo = new( ELeave ) CArrayFixFlat<TUint>( 1 );
+ iEnumConnInfo->Reset();
+
+ // Initialize last event time
+ iLastEventTime = iCmServer->EventQueue()->LastEventTime();
+
+ // Create a new object index (it stores the plug-in objects owned by this session)
+ iPlugins = CObjectIx::NewL();
+
+ // Initialize the object container using the object container index in the server
+ // (Object container provides unique ids for the objects owned by this session)
+ iContainer = iCmServer->NewContainerL();
+
+ //LOGEXITFN("CConnMonSession::ConstructL()")
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::~CConnMonSession
+// -----------------------------------------------------------------------------
+//
+CConnMonSession::~CConnMonSession()
+ {
+ LOGIT(".")
+ LOGENTRFN("CConnMonSession::~CConnMonSession()")
+
+ if ( iListening && ( iBearerAvailabilityThreshold == 1 ) )
+ {
+ // Resets plugin threshold, so plugin can stop sending bearer
+ // availability events when no longer needed.
+ SetPluginThreshold( EBearerAvailabilityThreshold, 0 );
+ }
+
+ // Cancel any 'receive' request
+ CancelReceiveEvent();
+
+ for ( TInt i = 0; i < iConnParams.Count(); i++ )
+ {
+ iConnParams[i].iRequests.Close();
+ }
+
+ iConnParams.Close();
+
+ if ( iEnumConnInfo != 0 )
+ {
+ iEnumConnInfo->Reset();
+ delete iEnumConnInfo;
+ iEnumConnInfo = NULL;
+ }
+
+ // Delete the object index
+ delete iPlugins;
+ iPlugins = NULL;
+
+ // Delete the object container
+ if ( iContainer != 0 )
+ {
+ iCmServer->RemoveContainer( iContainer );
+ iContainer = NULL;
+ }
+
+ // Check WLAN support
+ if ( iCmServer->Iap()->WlanSupport() )
+ {
+ // Delete WLAN session from WlanSessions array if exists
+ iCmServer->Iap()->WlanSupport()->DeleteWlanSession( this );
+ }
+
+ // Decrement session count, so server may terminate if no longer needed
+ iCmServer->DecrementSessions();
+
+ iCmServer = NULL;
+ iReceiveBuffer = NULL;
+
+ LOGEXITFN("CConnMonSession::~CConnMonSession()")
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::ServiceL
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::ServiceL( const RMessage2& aMessage )
+ {
+ //LOGENTRFN("CConnMonSession::ServiceL()")
+ TInt rc( KErrNone );
+
+ #ifdef _DEBUG
+ if ( aMessage.Function() != EReqReceiveEvent )
+ {
+ LOGIT(".")
+ LOGIT2("ServiceL: function %d, id %X", aMessage.Function(), aMessage.SecureId().iId)
+ }
+ #endif // _DEBUG
+
+ iMessage2 = aMessage;
+ switch ( aMessage.Function() )
+ {
+ case EReqGetConnectionCount:
+ rc = GetConnectionCountL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetConnectionInfo:
+ rc = GetConnectionInfo();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetSubConnectionInfo:
+ rc = GetSubConnectionInfo();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetIntAttribute:
+ rc = GetIntAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetUintAttribute:
+ rc = GetUintAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetBoolAttribute:
+ rc = GetBoolAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetStringAttribute:
+ rc = GetStringAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqGetPckgAttribute:
+ rc = GetPckgAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqSetIntAttribute:
+ rc = SetIntAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqSetUintAttribute:
+ rc = SetUintAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqSetBoolAttribute:
+ rc = SetBoolAttribute();
+ CompleteMessage( rc );
+ break;
+
+ case EReqSetStringAttribute:
+ rc = SetStringAttributeL();
+ CompleteMessage( rc );
+ break;
+
+ case EReqSetPckgAttribute:
+ rc = SetPckgAttribute();
+ CompleteMessage( rc );
+ break;
+
+ case EReqCancelAsyncRequest:
+ rc = CancelAsyncRequest();
+ CompleteMessage( rc );
+ break;
+
+ case EReqReceiveEvent: // TAny& aBuffer - async
+ ReceiveEventL( aMessage.Ptr0() );
+ break;
+
+ case EReqCancelReceiveEvent:
+ CancelReceiveEvent();
+ CompleteMessage( 0 );
+ break;
+
+ // Plug-in specific, fall-through intended
+ case EReqPluginCreateSubSession:
+ case EReqPluginCloseSubSession:
+ case EReqPluginRegisterAttribute:
+ case EReqPluginCancelRegisterAttribute:
+ case EReqPluginEvent:
+ case EReqPluginGetQuery:
+ case EReqPluginCancelGetQuery:
+ case EReqPluginAttribute:
+ ServicePluginL( aMessage );
+ break;
+
+ default:
+ iCmServer->PanicClient( EBadRequest );
+ break;
+ }
+ //LOGEXITFN("CConnMonSession::ServiceL()")
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CompleteMessage
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::CompleteMessage( const TInt aStatus )
+ {
+ // Check if async message
+ if ( aStatus != KRequestPending )
+ {
+ // Complete message
+ Message().Complete( aStatus );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetConnectionCountL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetConnectionCountL()
+ {
+ LOGENTRFN("CConnMonSession::GetConnectionCountL()")
+ TInt err( KErrNone );
+ TUint count( 0 );
+
+ // Call comms APIs
+ err = iCmServer->Iap()->EnumerateConnectionsL( count, *iEnumConnInfo );
+ LOGIT2("SERVER: EReqGetConnectionCount OUT: -> count %d, ret <%d>", count, err)
+
+ if ( KErrNone == err )
+ {
+ // Write "count" back to the client's address space
+ TPtrC8 d( reinterpret_cast<TUint8*>( &count ), sizeof( count ) );
+
+ err = Message().Write( 0, d );
+ if ( err != KErrNone )
+ {
+ LOGIT1("SERVER: EReqGetConnectionCount: -> error, Message().Write(0, d) returned <%d>", err)
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+
+ LOGIT("SERVER: EReqGetConnectionCount. -> RemoveObsoleteConnectionParams()")
+ // Remove obsolete connection settings
+ RemoveObsoleteConnectionParams();
+ }
+
+ LOGEXITFN1("CConnMonSession::GetConnectionCountL()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetConnectionInfo
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetConnectionInfo()
+ {
+ LOGENTRFN("CConnMonSession::GetConnectionInfo()")
+ TInt err( KErrNone );
+ TUint id( 0 );
+ TUint subConnectionCount( 1 );
+
+ TInt index = Message().Int0();
+
+ if ( !iEnumConnInfo )
+ {
+ err = KErrUnknown;
+ }
+ // Indexes given to client start from 1
+ else if ( ( index <= 0 ) || ( index > iEnumConnInfo->Count() ) )
+ {
+ err = KErrArgument;
+ }
+ else
+ {
+ // Enumerated connection IDs are stored in session
+ id = (*iEnumConnInfo)[index - 1];
+
+ // Get subconnection count
+ err = iCmServer->Iap()->GetConnectionInfo( id, subConnectionCount );
+ LOGIT4("SERVER: EReqGetConnectionInfo: index %d -> id %d, subConnCount %d, ret <%d>",
+ index, id, subConnectionCount, err)
+
+ if ( KErrNone == err )
+ {
+ // Write "id" back to the client's address space
+ TPtrC8 d( reinterpret_cast<TUint8*>( &id ), sizeof( id ) );
+
+ err = Message().Write( 1, d );
+ if ( KErrNone != err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ else
+ {
+ // Write "subConnectionCount" back to the client's address space
+ TPtrC8 e(
+ reinterpret_cast<TUint8*>( &subConnectionCount ),
+ sizeof( subConnectionCount ) );
+
+ err = Message().Write( 2, e );
+ if ( KErrNone != err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ }
+ }
+ }
+ LOGEXITFN1("CConnMonSession::GetConnectionInfo()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetSubConnectionInfo
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetSubConnectionInfo() const
+ {
+ LOGENTRFN("CConnMonSession::GetSubConnectionInfo()")
+ LOGEXITFN1("CConnMonSession::GetSubConnectionInfo()", KErrNotSupported)
+ return KErrNotSupported;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetIntAttributeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetIntAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::GetIntAttributeL()")
+ TInt err( KErrNone );
+ TInt value( 0 );
+
+ // Call comms APIs
+ err = iCmServer->Iap()->GetIntAttributeL( Message(), value );
+ LOGIT1("SERVER: CConnMonSession::GetIntAttributeL: Iap()->GetIntAttributeL <%d>", err)
+
+ // Check if this request should be served by a plug-in engine
+ if ( ( Message().Int0() >= EBearerIdGPRS ) &&
+ ( err != KErrNone ) &&
+ ( err != KRequestPending ) )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqGetIntAttribute, msg );
+ }
+
+ LOGIT5("SERVER: EReqGetIntAttribute. id %d, subConnId %d, attr %d -> value %d, ret <%d>",
+ Message().Int0(), Message().Int1(), Message().Int2(), value, err)
+ if ( KErrNone == err )
+ {
+ // Write "value" back to the client's address space
+ TPtrC8 d( reinterpret_cast<TUint8*>( &value ), sizeof( value ) );
+
+ err = Message().Write( KAttributeParameterIndex, d );
+ if ( KErrNone != err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ }
+
+ LOGEXITFN1("CConnMonSession::GetIntAttributeL()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetUintAttributeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetUintAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::GetUintAttributeL()")
+ TInt err( KErrNone );
+ TUint value( 0 );
+
+ TUint connectionId( Message().Int0() );
+ TInt attribute( Message().Int2() );
+
+ switch ( attribute )
+ {
+ case KDownlinkDataThreshold:
+ case KUplinkDataThreshold:
+ case KActivityTimeThreshold:
+ {
+ if ( iCmServer->Iap()->ConnectionExists( connectionId ) )
+ {
+ TConnSettings settings( 0, 0, 0 );
+ err = GetConnectionSettings( connectionId, settings );
+ if ( KErrNone == err )
+ {
+ if ( attribute == KDownlinkDataThreshold )
+ {
+ value = settings.iDLDataThreshold;
+ }
+ else if ( attribute == KUplinkDataThreshold )
+ {
+ value = settings.iULDataThreshold;
+ }
+ else
+ {
+ value = settings.iActivityTimeThreshold;
+ }
+ }
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+ }
+ break;
+
+ case KBearerAvailabilityThreshold:
+ value = iBearerAvailabilityThreshold;
+ break;
+ case KSignalStrengthThreshold:
+ value = iSignalStrengthThreshold;
+ break;
+ case KBearerGroupThreshold:
+ value = iBearerGroupThreshold;
+ break;
+
+ case KMobilePhoneNetworkMode:
+ {
+ LOGIT("GetUintAttributeL: case KMobilePhoneNetworkMode")
+
+ // Check network registration first
+ TInt registrationMode( ENetworkRegistrationNotAvailable );
+ err = iCmServer->Iap()->GetNetworkRegistrationMode( registrationMode );
+ if ( KErrNone == err )
+ {
+ if ( registrationMode == ENetworkRegistrationUnknown ||
+ registrationMode == ENetworkRegistrationNoService )
+ {
+ value = EConnMonNetworkModeUnknown;
+ }
+ else
+ {
+ RMobilePhone::TMobilePhoneNetworkMode networkMode;
+ err = iCmServer->Iap()->MobilePhone()->GetCurrentMode( networkMode );
+ if ( KErrNone == err )
+ {
+ LOGIT1("GetUintAttributeL: current phone network mode %d", networkMode)
+
+ TConnMonMobilePhoneNetworkMode connMonNetworkMode;
+ err = ConnMonUtils::MobilePhoneNetworkModeToConnMonMobilePhoneNetworkMode(
+ networkMode,
+ connMonNetworkMode );
+ if ( KErrNone == err )
+ {
+ value = connMonNetworkMode;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case KWlanScanMaxDelay:
+ // Check WLAN support for the given ID
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone == err )
+ {
+ err = iCmServer->Iap()->WlanSupport()->GetUintAttributeL( Message(), value );
+ }
+ break;
+
+ default:
+ {
+ LOGIT1("GetUintAttributeL: case %d", attribute)
+
+ // Call comms APIs
+ err = iCmServer->Iap()->GetUintAttributeL( Message(), value );
+
+ // Check if message will be completed later
+ if ( KRequestPending == err )
+ {
+ if ( KDownlinkData == attribute )
+ {
+ TConnRequest request( KDownlinkData, Message() );
+ SetConnectionRequest( connectionId, request );
+ }
+ else if ( KUplinkData == attribute )
+ {
+ TConnRequest request( KUplinkData, Message() );
+ SetConnectionRequest( connectionId, request );
+ }
+ }
+
+ // Check if this request should be served by a plug-in engine
+ if ( ( Message().Int0() >= EBearerIdGPRS ) &&
+ ( err != KErrNone ) &&
+ ( err != KRequestPending ) )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqGetUintAttribute, msg );
+ }
+ }
+ break;
+ }
+ LOGIT5("SERVER: EReqGetUintAttribute: id %d, subConnId %d, attr %d -> value %d, ret <%d>",
+ Message().Int0(), Message().Int1(), Message().Int2(), value, err )
+
+ if ( KErrNone == err )
+ {
+ // Write "value" back to the client's address space
+ TPtrC8 d( reinterpret_cast<TUint8*>( &value ), sizeof( value ) );
+
+ err = Message().Write( KAttributeParameterIndex, d );
+ if ( err != KErrNone )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ }
+
+ LOGEXITFN1("CConnMonSession::GetUintAttributeL()", err)
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetBoolAttributeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetBoolAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::GetBoolAttributeL()")
+ TInt err( KErrNone );
+ TBool value( EFalse );
+ TUint connectionId( Message().Int0() );
+ TUint attribute( Message().Int2() );
+
+ LOGIT2("SERVER: EReqGetBoolAttribute IN: id %d, attr %d", connectionId, attribute)
+ // Call comms APIs
+ err = iCmServer->Iap()->GetBoolAttributeL( Message(), value );
+
+ // Check if request was KConnectionActive and should be completed later
+ if ( ( err == KRequestPending ) && ( attribute == KConnectionActive ) )
+ {
+ TConnRequest request( KConnectionActive, Message() );
+ SetConnectionRequest( connectionId, request );
+ }
+
+ // Check if this request should be served by a plug-in engine
+ if ( ( ( connectionId >= EBearerIdGPRS ) &&
+ ( err != KErrNone ) &&
+ ( err != KRequestPending ) )
+ ||
+ ( ( attribute == KBearerAvailability ) &&
+ ( err == KErrCancel ) ) )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqGetBoolAttribute, msg );
+ }
+ LOGIT5("SERVER: EReqGetBoolAttribute OUT: id %d, subConnId %d, attr %d -> value %d, ret <%d>",
+ connectionId, Message().Int1(), attribute, value, err)
+
+ // Return if error or the request is pending and will be completed later.
+ if ( KErrNone == err )
+ {
+ // Write "value" back to the client's address space
+ TPtrC8 d( reinterpret_cast<TUint8*>( &value ), sizeof( value ) );
+
+ err = Message().Write( KAttributeParameterIndex, d );
+ if ( KErrNone != err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ }
+
+ LOGEXITFN1("CConnMonSession::GetBoolAttributeL()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetStringAttributeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetStringAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::GetStringAttributeL()")
+ TInt err( KErrNone );
+ TUint connectionId( Message().Int0() );
+ TUint attribute( Message().Int2() );
+ LOGIT2("SERVER: EReqGetStringAttribute IN: id %d, attribute %d", connectionId, attribute)
+
+ HBufC16* value = HBufC16::NewL( KConnMonMaxStringAttributeLength );
+ CleanupStack::PushL( value );
+
+ TPtr16 auxPtr( const_cast<TUint16*>( value->Des().Ptr() ), KConnMonMaxStringAttributeLength );
+ auxPtr.FillZ(); // Fill descriptor with zeros
+
+ // Check attribute
+ switch ( attribute )
+ {
+ case KWlanSsid:
+ // Check WLAN support
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone == err )
+ {
+ // Get string attribute from WLAN session, max SSID length is 32
+ err = iCmServer->Iap()->WlanSupport()->GetStringAttributeL( Message(), auxPtr );
+ }
+ break;
+
+ default:
+ // Call comms APIs
+ err = iCmServer->Iap()->GetStringAttribute( Message(), auxPtr );
+
+ // Check if this request should be served by a plug-in engine
+ if ( ( connectionId >= EBearerIdGPRS ) &&
+ ( KErrNone != err ) &&
+ ( KRequestPending != err ) )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqGetStringAttribute, msg );
+ }
+ break;
+ }
+ // Length of 'value' should be max 63 chars.
+ LOGIT5("SERVER: EReqGetStringAttribute OUT: id %d, subConnId %d, attr %d -> value >%s<, ret <%d>",
+ connectionId, Message().Int1(), attribute, auxPtr.PtrZ(), err)
+
+ CleanupStack::Pop( value );
+
+ if ( KErrNone == err )
+ {
+ // Write "value" back to the client's address space
+ err = Message().Write( KAttributeParameterIndex, auxPtr );
+ if ( err != KErrNone )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ }
+ delete value;
+
+ LOGEXITFN1("CConnMonSession::GetStringAttributeL()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetPckgAttributeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetPckgAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::GetPckgAttributeL()")
+ TInt err( KErrNone );
+
+ TUint connectionId( Message().Int0() );
+ TUint attribute( Message().Int2() );
+
+ switch ( attribute )
+ {
+ case KStartTime:
+ {
+ LOGIT("GetPckgAttributeL: attr == KStartTime")
+ TTime time;
+
+ // Call comms APIs
+ err = iCmServer->Iap()->GetStartTime( connectionId, time );
+ LOGIT2("GetPckgAttributeL: id %d, ret <%d>", connectionId, err)
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+
+ // Write "value" back to the client's address space
+ TPckgBuf<TTime> timePckg( time );
+ err = Message().Write( KAttributeParameterIndex, timePckg );
+ if ( KErrNone != err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+#ifdef _DEBUG
+ TBuf<KConnMonMaxStringAttributeLength> buf;
+ _LIT( KFormatStartTime, "%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%:3%+B" );
+ time.FormatL( buf, KFormatStartTime );
+ LOGIT1("GetPckgAttributeL: universal start time >%s<", buf.PtrZ())
+#endif // _DEBUG
+
+ break;
+ }
+
+ case KClientInfo:
+ {
+ LOGIT("GetPckgAttributeL: attr == KClientInfo")
+ // Client uids
+ TConnMonClientEnum clientEnum;
+
+ clientEnum.iCount = 0;
+ for ( TUint i = 0; i < KConnMonMaxClientUids; i++ )
+ {
+ clientEnum.iUid[i].iUid = 0;
+ }
+
+ // Call comms APIs
+ err = iCmServer->Iap()->GetUids( connectionId, clientEnum );
+ LOGIT2("GetPckgAttributeL: clients %d, ret <%d>", clientEnum.iCount, err)
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+
+ // Write "value" back to the client's address space
+ TPckgBuf<TConnMonClientEnum> clientEnumPckg( clientEnum );
+ err = Message().Write( KAttributeParameterIndex, clientEnumPckg );
+ if ( KErrNone != err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+ break;
+ }
+
+ case KNetworkNames:
+ {
+ LOGIT("GetPckgAttributeL: attr == KNetworkNames")
+
+ // Check if WLAN attribute and WLAN is supported
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone == err )
+ {
+ // This attribute generates WLAN scanning via WLAN engine.
+ // Async GetScanResults method is called and message will be completed
+ // later in session specific WlanSession class object
+ err = iCmServer->Iap()->WlanSupport()->GetNetworkNamesL( Message() );
+ }
+ return err;
+ }
+
+ case KWLANNetworks:
+ {
+ LOGIT("GetPckgAttributeL: attr == KWLANNetworks")
+
+ // Check buffer max length
+ TInt maxSize( Message().GetDesMaxLength( KAttributeParameterIndex ) );
+ if ( KErrBadDescriptor == maxSize )
+ {
+ LOGIT("GetPckgAttributeL: error, bad descriptor argument")
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ // Buffer's max length needs to be at least 2 beacause
+ // minimum information to be returned is the count of all
+ // networks and the count of returned networks.
+ if ( maxSize < 2 )
+ {
+ LOGIT1("GetPckgAttributeL: buffer too small %d", maxSize)
+ return KErrArgument;
+ }
+
+ // Get WLAN networks
+ RConnMonWLANNetworksArray wlanNetworks;
+ CleanupClosePushL( wlanNetworks );
+ iCmServer->Iap()->WlanSupport()->GetWLANNetworksL( wlanNetworks );
+
+ ConnMonWLANNetworksArrayPckg arr( wlanNetworks, maxSize );
+ CleanupStack::PopAndDestroy( &wlanNetworks );
+
+ if ( !arr.Buf() )
+ {
+ return KErrNoMemory;
+ }
+
+ // Write result back to the client
+ TInt res = Message().Write( KAttributeParameterIndex, ( *arr.Buf() ) );
+ if ( KErrNone != res )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ break;
+ }
+
+ case KWlanNetworks:
+ {
+ LOGIT("GetPckgAttributeL: attr == KWlanNetworks")
+
+ // Check if WLAN attribute and WLAN is supported
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+
+ // Check buffer max length
+ TInt maxSize( Message().GetDesMaxLength( KAttributeParameterIndex ) );
+ if ( KErrBadDescriptor == maxSize )
+ {
+ LOGIT("GetPckgAttributeL: error, bad descriptor argument")
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ // Buffer's max length needs to be at least 2 because
+ // minimum information to be returned is the count of all
+ // networks and the count of returned networks.
+ if ( maxSize < 2 )
+ {
+ LOGIT1("GetPckgAttributeL: buffer too small %d", maxSize)
+ return KErrArgument;
+ }
+
+ // This attribute generates WLAN scanning via WLAN engine.
+ // Async GetScanResults method is called and message will be completed
+ // later in session specific WlanSession class object
+ err = iCmServer->Iap()->WlanSupport()->GetWlanNetworksL( Message() );
+ return err;
+ }
+
+ case KWlanSsidNetworks:
+ {
+ LOGIT("GetPckgAttributeL: attr == KWlanSsidNetworks")
+
+ // Check if WLAN attribute and WLAN is supported
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+
+ // Check buffer max length
+ TInt maxSize( Message().GetDesMaxLength( KAttributeParameterIndex ) );
+ if ( KErrBadDescriptor == maxSize )
+ {
+ LOGIT("GetPckgAttributeL: error, bad descriptor argument")
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ // Buffer's max length needs to be at least 2 because
+ // minimum information to be returned is the count of all
+ // networks and the count of returned networks.
+ if ( maxSize < 2 )
+ {
+ LOGIT1("GetPckgAttributeL: buffer too small %d", maxSize)
+ return KErrArgument;
+ }
+
+ // This attribute generates WLAN scanning via WLAN engine.
+ // Async GetScanResults method is called and message will be completed
+ // later in session specific WlanSession class object
+ err = iCmServer->Iap()->WlanSupport()->GetWlanSsidNetworksL( Message() );
+ return err;
+ }
+
+ case KWlanCurrentNetwork:
+ {
+ LOGIT("GetPckgAttributeL: attr == KCurrentWlanNetwork")
+
+ // Check if WLAN attribute and WLAN is supported
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( err != KErrNone )
+ {
+ return err;
+ }
+
+ // Check buffer max length
+ TInt maxSize( Message().GetDesMaxLength( KAttributeParameterIndex ) );
+ if ( KErrBadDescriptor == maxSize )
+ {
+ LOGIT("GetPckgAttributeL: error, bad descriptor argument")
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ // Buffer's max length needs to be at least 2 because
+ // minimum information to be returned is the count of all
+ // networks and the count of returned networks.
+ if ( maxSize < 2 )
+ {
+ LOGIT1("GetPckgAttributeL: buffer too small %d", maxSize)
+ return KErrArgument;
+ }
+
+ RConnMonWlanNetworksPtrArray wlanNetwork;
+ ConnMonCleanupResetAndDestroyPushL( wlanNetwork );
+
+ err = iCmServer->Iap()->WlanSupport()->GetCurrentWlanNetworkL( wlanNetwork );
+ if ( err != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( &wlanNetwork );
+ return err;
+ }
+
+ CConnMonWlanNetworksPtrArrayPckg arr( wlanNetwork, maxSize );
+ CleanupStack::PopAndDestroy( &wlanNetwork );
+
+ if ( !arr.Buf() )
+ {
+ return KErrNoMemory;
+ }
+
+ // Write "value" back to the client's address space
+ err = Message().Write( KAttributeParameterIndex, ( *arr.Buf() ) );
+ if ( err != KErrNone )
+ {
+ // Panic client
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ return err;
+ }
+
+ case KWlanProbeRawBuffers:
+ {
+ LOGIT("GetPckgAttributeL: attr == KWlanProbeRawBuffers")
+
+ // Check if WLAN attribute and WLAN is supported
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+
+ // Check buffer max length
+ TInt maxSize( Message().GetDesMaxLength( KAttributeParameterIndex ) );
+ if ( KErrBadDescriptor == maxSize )
+ {
+ LOGIT("GetPckgAttributeL: error, bad descriptor argument")
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ // Buffer's max length needs to be at least 2 because
+ // minimum information to be returned is the count of all
+ // networks and the count of returned networks.
+ if ( maxSize < 2 )
+ {
+ LOGIT1("GetPckgAttributeL: buffer too small %d", maxSize)
+ return KErrArgument;
+ }
+
+ // This attribute generates WLAN scanning via WLAN engine.
+ // Async GetScanResults method is called and message will be completed
+ // later in session specific WlanSession class object
+ err = iCmServer->Iap()->WlanSupport()->GetWlanProbeRawBuffersL( Message() );
+ return err;
+ }
+
+ case KIapAvailability:
+ {
+ LOGIT1("GetPckgAttributeL: KIapAvailability, id %d", connectionId)
+ TConnMonIapInfo iaps;
+
+ // Connection ID attribute validity check
+ if ( ( connectionId != 0 ) &&
+ ( ( connectionId < EBearerIdGPRS ) ||
+ ( connectionId > EBearerIdVirtualVPN ) ) )
+ {
+ err = KErrArgument;
+ }
+ else if ( ( connectionId == EBearerIdGSM ) ||
+ ( connectionId == EBearerIdCDMA2000 ) )
+ {
+ err = KErrArgument;
+ }
+
+ if ( !err )
+ {
+ // Enable WLAN scan only if asking for all, WLAN or virtual IAPs
+ if ( ( connectionId == EBearerIdAll ) ||
+ ( connectionId == EBearerIdWLAN ) ||
+ ( connectionId == EBearerIdVirtualVPN ) )
+ {
+ iCmServer->Iap()->EnableWlanScan();
+ }
+
+ // If WLAN background scan is ON and request is asking for all-
+ // or virtual iaps, ConnMon will send availability changed
+ // event if availability change is detected.
+ err = iCmServer->GetAvailableIaps( connectionId, iaps );
+ }
+
+ LOGIT2("SERVER: GetPckgAttributeL: -> IAP count %d, err <%d>", iaps.iCount, err)
+ if ( err )
+ {
+ return err;
+ }
+
+ // Write result back to client
+ TConnMonIapInfoBuf iapBuf( iaps );
+ err = Message().Write( KAttributeParameterIndex, iapBuf );
+ if ( err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+ }
+ break;
+
+ case KSNAPsAvailability:
+ {
+ LOGIT("GetPckgAttributeL: KSNAPsAvailability")
+ TConnMonSNAPInfo snaps;
+
+ iCmServer->Iap()->EnableWlanScan();
+
+ // If WLAN background scan is ON, ConnMon will send availability
+ // changed event if availability change is detected.
+ iCmServer->GetAvailableSnaps( snaps );
+
+ // Write result back to the client
+ TConnMonSNAPInfoBuf snapBuf( snaps );
+
+ err = Message().Write( KAttributeParameterIndex, snapBuf );
+ if ( err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+ }
+ break;
+
+ case KAvailableSNAPsIds:
+ {
+ LOGIT("GetPckgAttributeL: KAvailableSNAPsIds")
+
+ TInt maxSize( Message().GetDesMaxLength( KAttributeParameterIndex ) ); // Max buffer length
+ if ( KErrBadDescriptor == maxSize )
+ {
+ LOGIT("SERVER: EReqGetPckgAttribute -> KAvailableSNAPsIds: bad descriptor")
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+ // Buffer's max length needs to be at least 2 beacause minimum
+ // information to be returned is the count of all networks and
+ // the count of returned networks.
+ if ( maxSize < 2 )
+ {
+ LOGIT("SERVER: EReqGetPckgAttribute -> KAvailableSNAPsIds: descriptor too small")
+ return KErrArgument;
+ }
+
+ iCmServer->Iap()->EnableWlanScan();
+
+ // If WLAN background scan is ON, ConnMon will send availability
+ // changed event if availability change is detected.
+ RArray<TConnMonId> availableSnapIds;
+ err = iCmServer->GetAvailableSnaps( availableSnapIds );
+ if ( err )
+ {
+ availableSnapIds.Close();
+ return err;
+ }
+
+ ConnMonIdsArrayPckg arr( availableSnapIds, maxSize );
+ availableSnapIds.Close();
+ if ( !arr.Buf() )
+ {
+ return KErrNoMemory;
+ }
+
+ err = Message().Write( KAttributeParameterIndex, (*arr.Buf()) );
+ if ( err )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+ }
+ break;
+
+ case KBearerGroupInfo:
+ {
+ LOGIT("GetPckgAttributeL: KBearerGroupInfo")
+
+ TBearerInfo bearerInfo;
+ TInt err = iCmServer->Iap()->GetBearerInfo( connectionId, bearerInfo );
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+ LOGIT1("CConnMonSession::GetPckgAttributeL, bearer %d", bearerInfo.iBearer)
+
+ TUint bearerMask( 0 );
+ TUint bearerMask2( 0 );
+
+ err = iCmServer->BearerGroupManager()->GetBearerGroups(
+ (TConnMonBearerInfo)bearerInfo.iBearer,
+ bearerMask,
+ bearerMask2 );
+ if ( KErrNone != err )
+ {
+ return err;
+ }
+ LOGIT2("CConnMonSession::GetPckgAttributeL, bearerMask %d, bearerMask2 %d", bearerMask, bearerMask2)
+
+ TConnMonBearerGroupInfo groupInfo;
+ groupInfo.iInternal = bearerInfo.iInternal;
+ groupInfo.iBearerGroups = bearerMask;
+ groupInfo.iBearerGroups2 = bearerMask2;
+
+ TConnMonBearerGroupInfoBuf groupInfoBuf( groupInfo );
+ err = Message().Write( KAttributeParameterIndex, groupInfoBuf );
+ if ( KErrNone != err )
+ {
+ LOGIT1("GetPckgAttributeL: error writing result to client <%d>", err)
+ iCmServer->PanicClient( EBadDescriptor );
+ return KErrBadDescriptor;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ LOGIT("GetPckgAttributeL: UNKNOWN attribute")
+ return KErrNotSupported;
+ }
+ }
+
+ LOGEXITFN("CConnMonSession::GetPckgAttributeL()")
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetIntAttribute
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetIntAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::SetIntAttributeL()")
+ TInt err( KErrNone );
+
+ TUint connectionId( Message().Int0() );
+ TUint attribute( Message().Int2() );
+ TUint value( Message().Int3() );
+
+ if ( KWlanScanCacheLifetime == attribute )
+ {
+ // Check WLAN support for the given id
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone == err )
+ {
+ err = iCmServer->Iap()->WlanSupport()->SetIntAttributeL( Message(), value );
+ }
+ }
+ else if ( connectionId >= EBearerIdGPRS )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqSetIntAttribute, msg );
+ }
+ else
+ {
+ err = KErrNotSupported;
+ }
+
+ LOGEXITFN1("CConnMonSession::SetIntAttributeL()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetUintAttribute
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetUintAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::SetUintAttributeL()")
+ TInt err( KErrNone );
+
+ TUint connectionId( Message().Int0() );
+ TUint attribute( Message().Int2() );
+ TUint value( Message().Int3() );
+
+ switch ( attribute )
+ {
+ case KDownlinkDataThreshold:
+ case KUplinkDataThreshold:
+ case KActivityTimeThreshold:
+ {
+ if ( connectionId > KMaxConnectionId )
+ {
+ err = KErrArgument;
+ }
+ else if ( !iCmServer->Iap()->ConnectionExists( connectionId ) )
+ {
+ err = KErrNotFound;
+ }
+ else
+ {
+ err = AdjustThresholdToAllowedRange( connectionId, attribute, value );
+ if ( KErrNone == err )
+ {
+ TConnSettings settings( 0, 0, 0 );
+ GetConnectionSettings( connectionId, settings );
+ if ( attribute == KDownlinkDataThreshold )
+ {
+ settings.iDLDataThreshold = value;
+ }
+ else if ( attribute == KUplinkDataThreshold )
+ {
+ settings.iULDataThreshold = value;
+ }
+ else // KActivityTimeThreshold
+ {
+ settings.iActivityTimeThreshold = value;
+ }
+ err = SetConnectionSettings( connectionId, settings );
+ }
+ }
+ }
+ break;
+
+ case KBearerAvailabilityThreshold:
+ err = SetPluginThreshold( EBearerAvailabilityThreshold, value );
+ if ( err != KErrNone )
+ {
+ // Set anyway
+ iBearerAvailabilityThreshold = value;
+ err = KErrNone;
+ }
+ if ( iListening && ( iBearerAvailabilityThreshold > 0 ) )
+ {
+ iCmServer->Iap()->WakeUpNotifications();
+ }
+ break;
+
+ case KSignalStrengthThreshold:
+ iSignalStrengthThreshold = value;
+ if ( iListening && ( iSignalStrengthThreshold > 0 ) )
+ {
+ iCmServer->Iap()->WakeUpNotifications();
+ }
+ err = KErrNone;
+ break;
+
+ case KBearerGroupThreshold:
+ iBearerGroupThreshold = value;
+ LOGIT1("SetUintAttributeL: bearer group threshold set %d", iBearerGroupThreshold)
+ break;
+
+ case KWlanScanMaxDelay:
+ // Check WLAN support for the given id
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone == err )
+ {
+ err = iCmServer->Iap()->WlanSupport()->SetUintAttributeL( Message(), value );
+ }
+ break;
+
+ default:
+ LOGIT1("SERVER: CConnMonSession::SetUintAttributeL() default case %d", attribute)
+ // Call comms APIs
+ err = iCmServer->Iap()->SetUintAttribute( Message(), value );
+
+ if ( ( Message().Int0() >= EBearerIdGPRS ) && ( err != KErrNone ) )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqSetUintAttribute, msg );
+ }
+ break;
+ }
+
+ LOGEXITFN1("CConnMonSession::SetUintAttributeL()", err)
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetBoolAttributeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetBoolAttribute()
+ {
+ LOGENTRFN("CConnMonSession::SetBoolAttribute()")
+ TInt err( KErrNotSupported );
+ TUint attribute( Message().Int2() );
+ LOGIT3("SERVER: EReqSetBoolAttribute IN: id %d, attr %d, value %d",
+ Message().Int0(), attribute, Message().Int3())
+
+ if ( ( attribute == KConnectionStop ) || ( attribute == KConnectionStopAll ) )
+ {
+ err = iCmServer->Iap()->SetBoolAttribute( Message() );
+ }
+ else if ( Message().Int0() >= EBearerIdGPRS )
+ {
+ RMessage2 msg = Message();
+ err = iCmServer->SendRequestToPlugin( EReqSetBoolAttribute, msg );
+ }
+
+ LOGEXITFN1("CConnMonSession::SetBoolAttribute()", err)
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetStringAttribute
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetStringAttributeL()
+ {
+ LOGENTRFN("CConnMonSession::SetStringAttributeL()")
+ TInt err( KErrNone );
+ TUint connectionId( Message().Int0() );
+ TUint attribute( Message().Int2() );
+ LOGIT2("SERVER: EReqSetStringAttribute: id %d, attr %d", connectionId, attribute)
+
+ // Check attribute
+ switch ( attribute )
+ {
+ case KWlanSsid:
+ {
+ // Check WLAN support
+ err = iCmServer->Iap()->WlanSupportCheck( connectionId );
+ if ( KErrNone == err )
+ {
+ // Get descriptor argument length
+ TInt size = Message().GetDesLength( KAttributeParameterIndex );
+ if ( size < 0 )
+ {
+ LOGIT("SetStringAttributeL: error with descriptor argument")
+ err = size; // KErrArgument or KErrBadDescriptor
+ }
+ else if ( size > CConnMonWlanNetwork::KMaxNameLength )
+ {
+ LOGIT1("SetStringAttributeL: string too long %d", size)
+ err = KErrTooBig;
+ }
+ else
+ {
+ // Read descriptor argument from message
+ TBuf<CConnMonWlanNetwork::KMaxNameLength> value;
+ Message().Read( KAttributeParameterIndex, value );
+
+ #ifdef _DEBUG
+ // One letter longer than string, since we are adding a '\0' when printing
+ TBuf<CConnMonWlanNetwork::KMaxNameLength + 1> debugName( value );
+ LOGIT2("SetStringAttributeL: string >%s<, length %d", debugName.PtrZ(), value.Length())
+ #endif // _DEBUG
+
+ // Set string
+ err = iCmServer->Iap()->WlanSupport()->SetStringAttributeL( Message(), value );
+ }
+ }
+ }
+ break;
+
+ default:
+ err = KErrNotSupported;
+ break;
+ }
+
+ LOGEXITFN1("CConnMonSession::SetStringAttributeL()", err)
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetPckgAttribute
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetPckgAttribute() const
+ {
+ return KErrNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CancelAsyncRequest
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::CancelAsyncRequest()
+ {
+ LOGENTRFN("CConnMonSession::CancelAsyncRequest()")
+
+ // Defined in TConnMonAsyncRequest
+ TInt requestToCancel = Message().Int0();
+ LOGIT1("SERVER: EReqCancelAsyncRequest, req %d", requestToCancel)
+
+ if ( ( EConnMonGetPckgAttribute == requestToCancel ) ||
+ ( EConnMonGetBoolAttribute == requestToCancel ) ||
+ ( EConnMonGetIntAttribute == requestToCancel ) )
+ {
+ // Check WLAN support
+ if ( iCmServer->Iap()->WlanSupport() )
+ {
+ // Cancel possible wlan requests
+ iCmServer->Iap()->WlanSupport()->CancelAsyncRequest( Message() );
+ }
+ }
+
+ if ( EConnMonGetUintAttribute == requestToCancel )
+ {
+ // Complete all pending data volume requests with status 'KErrCancel'
+ for ( TInt i = 0; i < iConnParams.Count(); i++ )
+ {
+ CompleteDataVolumeRequests( iConnParams[i].iConnectionId, 0, 0, KErrCancel );
+ }
+ }
+ else if ( EConnMonGetBoolAttribute == requestToCancel )
+ {
+ // Complete all pending activity requests with status 'KErrCancel'
+ for ( TInt i = 0; i < iConnParams.Count(); i++ )
+ {
+ CompleteActivityRequests( iConnParams[i].iConnectionId, EFalse, KErrCancel );
+ }
+ }
+
+ // Complete all pending plugin requests (of type Message().Int0()) with 'KErrCancel'
+ RThread clientThread;
+
+ TInt err = Message().Client( clientThread );
+ if ( KErrNone == err )
+ {
+ iCmServer->CancelAttributeRequestsFromPlugins( clientThread, Message().Int0() );
+ clientThread.Close();
+ }
+
+ LOGEXITFN1("CConnMonSession::CancelAsyncRequest()", err)
+ return err;
+
+ // It is not possible to cancel other async requests at the moment because they
+ // are completed right away in the server side. Note. the client's request for a new
+ // event (EReqReceiveEvent) is cancelled by calling CancelNotifications()
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::ReceiveEventL
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::ReceiveEventL( const TAny* aBuffer )
+ {
+ __ASSERT_DEBUG( !iReceiveActive, PanicServer( EReceiveAlreadyActive ) );
+
+ //LOGIT("SERVER: EReqReceiveEvent")
+
+ if ( !iListening )
+ {
+ // Set status first
+ iListening = ETrue;
+
+ // Start event notifiers if not already there
+ iCmServer->Iap()->ListenL();
+
+ // Want events from now on...
+ iLastEventTime = iCmServer->EventQueue()->LastEventTime();
+
+ // Set the threshold to the plugin (to start the plugin events)
+ if ( iBearerAvailabilityThreshold == 1 )
+ {
+ iBearerAvailabilityThreshold = 0; // To cause a change 0 -> 1
+ SetPluginThreshold( EBearerAvailabilityThreshold, 1 );
+ }
+ }
+
+ // Remember the 'receive request'
+ iReceiveMessage = Message();
+ iReceiveBuffer = aBuffer;
+ iReceiveActive = ETrue;
+
+ // Check for immediate fulfilment
+ iCmServer->EventQueue()->CheckEvents( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CancelReceiveEvent
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::CancelReceiveEvent()
+ {
+ if ( iReceiveActive )
+ {
+ LOGIT("SERVER: EReqCancelReceiveEvent")
+ iReceiveMessage.Complete( KErrCancel );
+ iReceiveActive = EFalse;
+ }
+
+ // Stop event watchers (if this is the last session wanting events)
+ if ( iListening )
+ {
+ // Reset plugin's threshold relating to availability events
+ // (to stop the plugin events when not needed)
+ if ( iBearerAvailabilityThreshold == 1 )
+ {
+ SetPluginThreshold( EBearerAvailabilityThreshold, 0 );
+ iBearerAvailabilityThreshold = 1; // Restore
+ }
+
+ // Stop listening
+ iCmServer->Iap()->CancelListen();
+ iListening = EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::IsListening
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonSession::IsListening() const
+ {
+ return iListening;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CanReceiveEvent
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonSession::CanReceiveEvent() const
+ {
+ return iReceiveActive;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SendEventToClient
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonSession::SendEventToClient( const TEvent& aEvent )
+ {
+ if ( aEvent.iTime > iLastEventTime )
+ {
+ // Client wants only new events
+ iLastEventTime = aEvent.iTime;
+
+ switch ( aEvent.iInfo.iEventType )
+ {
+ case EConnMonDownlinkDataThreshold:
+ case EConnMonUplinkDataThreshold:
+ {
+ TUint threshold( 0 );
+ TUint smallestThreshold( 0 );
+ CalculateAdjustedThreshold( aEvent.iInfo, threshold, smallestThreshold );
+
+ if ( ( threshold > 0 ) && ( smallestThreshold > 0 ) )
+ {
+ TUint rounded = smallestThreshold * ( aEvent.iInfo.iData / smallestThreshold );
+ if ( ( aEvent.iInfo.iData % smallestThreshold ) > ( smallestThreshold / 2 ) )
+ {
+ rounded += smallestThreshold;
+ }
+ if ( rounded % threshold != 0 )
+ {
+ return EFalse;
+ }
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ break;
+
+ case EConnMonConnectionActivityChange:
+ {
+ TConnSettings settings( 0, 0, 0 );
+ GetConnectionSettings( aEvent.iInfo.iConnectionId, settings );
+ if ( settings.iActivityTimeThreshold == 0 )
+ {
+ return EFalse;
+ }
+ }
+ break;
+
+ case EConnMonBearerAvailabilityChange:
+ {
+ if ( iBearerAvailabilityThreshold == 0 )
+ {
+ return EFalse;
+ }
+ }
+ break;
+
+ case EConnMonSignalStrengthChange:
+ {
+ if ( iSignalStrengthThreshold == 0 )
+ {
+ return EFalse;
+ }
+ }
+ break;
+
+ case EConnMonBearerInfoChange:
+ case EConnMonBearerChange:
+ {
+ // Send only either EConnMonBearerChange or EConnMonBearerInfoChange event
+
+ if ( iBearerGroupThreshold == 0 &&
+ aEvent.iInfo.iEventType == EConnMonBearerInfoChange )
+ {
+ return EFalse;
+ }
+ else if ( iBearerGroupThreshold > 0 &&
+ aEvent.iInfo.iEventType == EConnMonBearerChange )
+ {
+ return EFalse;
+ }
+ }
+ break;
+
+ case EConnMonBearerGroupChange:
+ {
+ if ( iBearerGroupThreshold == 0 )
+ {
+ return EFalse;
+ }
+ }
+ break;
+
+ case EConnMonIapAvailabilityChange:
+ case EConnMonSNAPsAvailabilityChange:
+ {
+ if ( aEvent.iExtra.iPtr )
+ {
+ TPtrC8 tempDes( aEvent.iExtra.iPtr, aEvent.iExtra.iSize );
+ TConnMonExtraBuf notiBuf( tempDes );
+ TInt err = iReceiveMessage.Write( 1, notiBuf );
+ if ( err != KErrNone )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ iReceiveActive = EFalse;
+ return ETrue;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Send the event info to the client
+ TPtr8 n( (TUint8*) &( aEvent.iInfo ), sizeof( TEventInfo ), sizeof( TEventInfo ) );
+
+ TInt res = iReceiveMessage.Write( 0, n );
+ if ( res != KErrNone )
+ {
+ iCmServer->PanicClient( EBadDescriptor );
+ }
+ else
+ {
+ // Complete the message
+ iReceiveMessage.Complete( KErrNone );
+ }
+
+ iReceiveActive = EFalse;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CompleteDataVolumeRequests
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::CompleteDataVolumeRequests(
+ const TUint& aConnectionId,
+ const TUint& aDlVolume,
+ const TUint& aUlVolume,
+ const TInt& aStatus )
+ {
+ TInt index( 0 );
+
+ // Find requests for the current connection
+ for ( index = 0; index < iConnParams.Count(); index++ )
+ {
+ if ( iConnParams[index].iConnectionId == aConnectionId )
+ {
+ break;
+ }
+ }
+
+ if ( index == iConnParams.Count() )
+ {
+ return KErrArgument;
+ }
+
+ // Send values to the the client
+ // Loop to find any pending data volume requests on this connection
+ for ( TInt i = 0; i < iConnParams[index].iRequests.Count(); i++ )
+ {
+ TConnRequest* req = &( iConnParams[index].iRequests[i] );
+ TInt err( KErrNone );
+
+ if ( req->iType == KDownlinkData || req->iType == KUplinkData )
+ {
+ if ( ( aStatus == KErrNone ) || ( aStatus == KErrCancel ) )
+ {
+ if ( req->iType == KDownlinkData )
+ {
+ TPtr8 n( (TUint8*) &aDlVolume, sizeof( TUint ), sizeof( TUint ) );
+
+ err = req->iMessage.Write( KAttributeParameterIndex, n );
+ }
+ else
+ {
+ TPtr8 m( (TUint8*) &aUlVolume, sizeof( TUint ), sizeof( TUint ) );
+
+ err = req->iMessage.Write( KAttributeParameterIndex, m );
+ }
+
+ if ( err != KErrNone )
+ {
+ iCmServer->PanicClient( req->iMessage, EBadDescriptor );
+ }
+ }
+
+ // Complete the request
+ req->iMessage.Complete( aStatus );
+
+ // Remove the completed request from the array
+ iConnParams[index].iRequests.Remove( i );
+ i--;
+ }
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CompleteActivityRequests
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::CompleteActivityRequests(
+ const TUint& aConnectionId,
+ const TBool& aActivity,
+ const TInt& aStatus )
+ {
+ TInt index( 0 );
+
+ // Find requests for the current connection
+ for ( index = 0; index < iConnParams.Count(); index++ )
+ {
+ if ( iConnParams[index].iConnectionId == aConnectionId )
+ {
+ break;
+ }
+ }
+
+ if ( index == iConnParams.Count() )
+ {
+ return KErrArgument;
+ }
+
+ // Send values to the the client
+ // Loop to find any pending activity requests on this connection
+ for ( TInt i = 0; i < iConnParams[index].iRequests.Count(); i++ )
+ {
+ TConnRequest* req = &( iConnParams[index].iRequests[i] );
+ TInt err( KErrNone );
+
+ if ( req->iType == KConnectionActive )
+ {
+ if ( aStatus == KErrNone )
+ {
+ TPtr8 n( (TUint8*) &aActivity, sizeof( TBool ), sizeof( TBool ) );
+
+ err = req->iMessage.Write( KAttributeParameterIndex, n );
+ if ( err != KErrNone )
+ {
+ iCmServer->PanicClient( req->iMessage, EBadDescriptor );
+ }
+ }
+
+ // Complete the request
+ req->iMessage.Complete( aStatus );
+
+ // Remove the completed request from the array
+ iConnParams[index].iRequests.Remove( i );
+ i--;
+ }
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetConnectionSettings
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetConnectionSettings(
+ const TUint aConnId,
+ const TConnSettings& aSettings )
+ {
+ if ( aConnId <= KMaxConnectionId )
+ {
+ if ( !IsConnectionValid( aConnId ) )
+ {
+ RemoveConnectionParams( aConnId );
+ return KErrNotFound;
+ }
+ }
+ else
+ {
+ return KErrArgument;
+ }
+
+ TConnParams connParams( aConnId );
+ TInt index = iConnParams.Find( connParams, TConnParams::MatchId );
+
+ if ( KErrNotFound == index )
+ {
+ connParams.iSettings = aSettings;
+ iConnParams.Append( connParams );
+ }
+ else
+ {
+ iConnParams[index].iSettings = aSettings;
+ }
+
+ if ( iListening )
+ {
+ iCmServer->Iap()->WakeUpNotifications( aConnId );
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetConnectionSettings
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetConnectionSettings(
+ const TUint aConnId,
+ TConnSettings& aSettings )
+ {
+ TInt index( 0 );
+
+ for ( index = 0; index < iConnParams.Count(); index++ )
+ {
+ if ( iConnParams[index].iConnectionId == aConnId )
+ {
+ break;
+ }
+ }
+
+ if ( index < iConnParams.Count() )
+ {
+ aSettings = iConnParams[index].iSettings;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetConnectionRequest
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetConnectionRequest(
+ const TUint aConnId,
+ const TConnRequest& aRequest )
+ {
+ if ( !IsConnectionValid( aConnId ) )
+ {
+ RemoveConnectionParams( aConnId );
+ return KErrNotFound;
+ }
+
+ TConnParams connParams( aConnId );
+ TInt index = iConnParams.Find( connParams, TConnParams::MatchId );
+
+ if ( KErrNotFound == index )
+ {
+ connParams.iRequests.Append( aRequest );
+ iConnParams.Append( connParams );
+ }
+ else
+ {
+ iConnParams[index].iRequests.Append( aRequest );
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::RemoveConnectionParams
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::RemoveConnectionParams( const TUint aConnId )
+ {
+ TInt index( 0 );
+
+ for ( index=0; index < iConnParams.Count(); index++ )
+ {
+ if ( iConnParams[index].iConnectionId == aConnId )
+ {
+ break;
+ }
+ }
+
+ if ( index == iConnParams.Count() )
+ {
+ return KErrNotFound;
+ }
+ else
+ {
+ // Complete any outstanding requests on this connection
+ CompleteDataVolumeRequests( aConnId, 0, 0, KErrDisconnected );
+ CompleteActivityRequests( aConnId, EFalse, KErrDisconnected );
+
+ // Free resources
+ iConnParams[index].iRequests.Close();
+
+ // Remove the whole entry
+ iConnParams.Remove( index );
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::GetBearerThreshold
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::GetBearerThreshold(
+ const TInt& aThresholdType,
+ TUint& aThreshold ) const
+ {
+ if ( !iListening )
+ {
+ aThreshold = 0;
+ return KErrNone;
+ }
+
+ if ( aThresholdType == EBearerAvailabilityThreshold )
+ {
+ aThreshold = iBearerAvailabilityThreshold;
+ }
+ else if ( aThresholdType == ESignalStrengthThreshold )
+ {
+ aThreshold = iSignalStrengthThreshold;
+ }
+ else
+ {
+ return KErrArgument;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::ServicePluginL
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::ServicePluginL( const RMessage2& aMessage )
+ {
+ TInt rc( 0 );
+
+ if ( !FeatureManager::FeatureSupported( KFeatureIdConnMonExtension ) )
+ {
+ aMessage.Complete( KErrNotSupported );
+ LOGIT("SERVER: Plugins are not supported")
+ return;
+ }
+
+ switch ( aMessage.Function() )
+ {
+ // CREATE PLUGIN
+ case EReqPluginCreateSubSession:
+ {
+ if ( aMessage.Int0() < EBearerIdGPRS )
+ {
+ aMessage.Complete( KErrArgument );
+ }
+ else
+ {
+ NewPluginL( aMessage.Int0() );
+ aMessage.Complete( KErrNone );
+ LOGIT1("SERVER: Plugin has registered, id %d", aMessage.Int0())
+ }
+
+ break;
+ }
+
+ // DELETE PLUGIN
+ case EReqPluginCloseSubSession:
+ {
+ DeletePlugin( aMessage.Int3() );
+ aMessage.Complete( KErrNone );
+
+ break;
+ }
+
+ // SERVICE PLUGIN'S REQUEST
+ default:
+ {
+ CPlugin* plugin = PluginFromHandle( aMessage.Int3() );
+
+ if ( !plugin )
+ {
+ iCmServer->PanicClient( EConnMonBadHandle );
+ break;
+ }
+
+ switch ( aMessage.Function() )
+ {
+ case EReqPluginRegisterAttribute:
+ {
+ TUint attribute( aMessage.Int0() );
+
+ rc = plugin->RegisterAttribute( attribute );
+ aMessage.Complete( rc );
+
+ // Threshold can be set to the plugin only after completing the plugin's request
+ if ( ( rc == KErrNone ) && ( attribute == KBearerAvailabilityThreshold ) )
+ {
+ plugin->GetQuery();
+ }
+ break;
+ }
+ case EReqPluginCancelRegisterAttribute:
+ {
+ rc = plugin->CancelRegisterAttribute( aMessage.Int0() );
+ aMessage.Complete( rc );
+ break;
+ }
+ case EReqPluginEvent:
+ {
+ TEventInfo eventInfo;
+ TUint8* ptrData( NULL );
+ TInt dataSize( 0 );
+
+ rc = plugin->Event( aMessage, eventInfo, ptrData, dataSize );
+ aMessage.Complete( rc );
+
+ if ( rc == KErrNone )
+ {
+ // Send the event to the clients
+ iCmServer->EventQueue()->Add( eventInfo, ptrData, dataSize );
+
+ LOGIT3("SERVER: EVENT from PLUGIN-> id %d, event %d, data %d",
+ eventInfo.iConnectionId, eventInfo.iEventType, eventInfo.iData)
+
+ if ( ( eventInfo.iConnectionId == EBearerIdLAN ) &&
+ ( eventInfo.iEventType == EConnMonBearerAvailabilityChange ) )
+ {
+ if ( eventInfo.iData == 1 )
+ {
+ // LAN bearer has become available
+ // Check if there are any LAN IAPs.
+ TFullIapInfo* iaps = NULL;
+ iaps = new( ELeave ) TFullIapInfo;
+ CleanupStack::PushL( iaps );
+
+ CIapSupport* iapSupport = CIapSupport::NewL();
+ CleanupStack::PushL( iapSupport );
+
+ iapSupport->GetIapsFromCommDbL( EBearerIdLAN, *iaps );
+
+ CleanupStack::PopAndDestroy( iapSupport );
+ iapSupport = NULL;
+
+ // Show the UI dialog only if there are LAN IAPs in the commDB.
+ if ( iaps->iCount > 0 )
+ {
+ CUiDialogAO* dialog = NULL;
+ // Show a dialog on the UI and ask the user to select the
+ // LAN network. CUiDialog is a one shot active object. It
+ // will save the user's LAN network preference to ConnMonIap.
+ // Use TRAPD because all SDKs don't have this dialog that is OK.
+ TRAPD( leaveCode, dialog = CUiDialogAO::NewL( iCmServer ) );
+
+ if ( leaveCode == KErrNone )
+ {
+ dialog->Start();
+ }
+ }
+ CleanupStack::PopAndDestroy( iaps );
+ }
+ else
+ {
+ // LAN bearer is not anymore available
+
+ // Reset user's LAN network selection
+ iCmServer->Iap()->ResetEndUserLanPreference();
+
+ LOGIT("CConnMonSession::ServicePluginL triggered HandleAvailabilityChange()")
+
+ ( (CConnMonServer*)Server() )->AvailabilityManager()
+ ->HandleAvailabilityChange();
+ }
+ }
+ }
+ break;
+ }
+ case EReqPluginGetQuery:
+ {
+ rc = plugin->GetQuery( aMessage );
+
+ // This will be completed later by the CPlugin object
+ break;
+ }
+ case EReqPluginCancelGetQuery:
+ {
+ rc = plugin->CancelGetQuery();
+ aMessage.Complete( rc );
+ break;
+ }
+ case EReqPluginAttribute:
+ {
+ rc = plugin->Attribute( aMessage );
+ aMessage.Complete( rc );
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::PluginFromHandle
+// Will return NULL if parameter aHandle is invalid
+// -----------------------------------------------------------------------------
+//
+CPlugin* CConnMonSession::PluginFromHandle( const TUint aHandle )
+ {
+ CPlugin* plugin = reinterpret_cast<CPlugin*>( iPlugins->At( aHandle ) );
+ return plugin;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::NewPluginL
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::NewPluginL( const TUint aConnectionId )
+ {
+ // Create a new plugin object
+ CPlugin* plugin = CPlugin::NewL( this, aConnectionId );
+
+ // Ensure that the reference count is decremented if we leave.
+ // When ref count becomes zero, CObject::Close() deletes the object.
+ CleanupClosePushL( *plugin );
+
+ // Add object to object container to generate unique id
+ iContainer->AddL( ( CObject* ) plugin );
+
+ // Add object to object index; this returns a unique handle
+ TInt handle = iPlugins->AddL( ( CObject* ) plugin );
+
+ // Object is now owned by this session, reference count is correct.
+ CleanupStack::Pop( plugin );
+
+ // Write the handle to the client
+ TPckg<TInt> handlePckg( handle );
+
+ TInt res = Message().Write( KAttributeParameterIndex, handlePckg );
+
+ if ( res != KErrNone )
+ {
+ // Removes from object index and destroys the object
+ iPlugins->Remove( handle );
+
+ iCmServer->PanicClient( EBadDescriptor );
+ return;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::DeletePlugin
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::DeletePlugin( const TUint aHandle )
+ {
+ CPlugin* plugin = reinterpret_cast<CPlugin*>( iPlugins->At( aHandle ) );
+
+ if ( !plugin )
+ {
+ iCmServer->PanicClient( EConnMonBadHandle );
+ }
+ else
+ {
+ // Removes from object index and destroys the object
+ iPlugins->Remove( aHandle );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SendRequestToPlugin
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SendRequestToPlugin( const TInt aType, const RMessage2& aMessage )
+ {
+ //LOGENTRFN("CConnMonSession::SendRequestToPlugin()")
+ TInt ret( KErrNotSupported );
+
+ TInt count = iPlugins->ActiveCount();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CPlugin* plugin = reinterpret_cast<CPlugin*>( ( *iPlugins )[i] );
+
+ if ( plugin )
+ {
+ if ( aType == EReqGetIntAttribute ||
+ aType == EReqGetUintAttribute ||
+ aType == EReqGetBoolAttribute ||
+ aType == EReqGetStringAttribute ||
+ aType == EReqGetPckgAttribute )
+ {
+ ret = plugin->GetAttributeForClient( aType, aMessage );
+
+ // Asynchronous
+ if ( ret == KRequestPending )
+ {
+ return ret;
+ }
+ }
+ else if ( aType == EReqSetIntAttribute ||
+ aType == EReqSetUintAttribute ||
+ aType == EReqSetBoolAttribute ||
+ aType == EReqSetStringAttribute ||
+ aType == EReqSetPckgAttribute ||
+ aType == EReqInternalSetThreshold ||
+ aType == EReqInternalResetThreshold )
+ {
+ ret = plugin->SetAttributeForClient( aType, aMessage );
+
+ // Synchronous
+ if ( ret == KErrNone )
+ {
+ return ret;
+ }
+ }
+ else
+ {
+ return KErrNotSupported;
+ }
+ }
+ }
+
+ //LOGEXITFN("CConnMonSession::SendRequestToPlugin()")
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CancelAttributeRequestFromPlugin
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::CancelAttributeRequestFromPlugin(
+ const RThread& aClient,
+ const TInt aType )
+ {
+ TInt count = iPlugins->ActiveCount();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CPlugin* plugin = reinterpret_cast<CPlugin*>( ( *iPlugins )[i] );
+
+ if ( plugin )
+ {
+ plugin->CancelGetAttributeForClient( aClient, aType );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::SetPluginThreshold
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::SetPluginThreshold( const TInt aType, const TUint aValue )
+ {
+ TUint globalThBefore( 0 );
+ TUint globalThAfter( 0 );
+ TUint connectionId( 0 );
+ TBool internal( EFalse );
+
+ if ( !FeatureManager::FeatureSupported( KFeatureIdConnMonExtension ) )
+ {
+ return KErrNotSupported;
+ }
+
+ if ( aType != EBearerAvailabilityThreshold && aType != ESignalStrengthThreshold )
+ {
+ return KErrNotSupported;
+ }
+
+ // At the moment a common threshold is used for all the bearers.
+ // When 'internal' is true threshold will be set in every plugin.
+ internal = ETrue;
+
+ // Get the global threshold before changing session threshold
+ iCmServer->CalculateThreshold( connectionId, aType, globalThBefore );
+
+ if ( aType == EBearerAvailabilityThreshold )
+ {
+ // Set the new threshold value
+ iBearerAvailabilityThreshold = aValue;
+ }
+ else if ( aType == ESignalStrengthThreshold )
+ {
+ // Set the new threshold value
+ iSignalStrengthThreshold = aValue;
+ }
+
+ // Get the global threshold after changing our threshold
+ iCmServer->CalculateThreshold( connectionId, aType, globalThAfter );
+
+ if ( globalThBefore != globalThAfter )
+ {
+ // Global threshold has changed -> send to plug-in engines
+ if ( internal )
+ {
+ if ( aValue == 1 )
+ {
+ iCmServer->SendRequestToPlugin( EReqInternalSetThreshold, Message(), ETrue );
+ }
+ else
+ {
+ iCmServer->SendRequestToPlugin( EReqInternalResetThreshold, Message(), ETrue );
+ }
+ }
+ else
+ {
+ iCmServer->SendRequestToPlugin( EReqSetUintAttribute, Message(), ETrue );
+ }
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::IsConnectionValid
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonSession::IsConnectionValid( const TUint aConnId )
+ {
+ LOGENTRFN("CConnMonSession::IsConnectionValid()")
+ TBool result( EFalse );
+
+ // Is connection valid anymore
+ TUint subConnectionCount( 0 );
+ TInt err = iCmServer->Iap()->GetConnectionInfo( aConnId, subConnectionCount );
+ if ( err != KErrNone )
+ {
+ result = EFalse;
+ }
+ else
+ {
+ result = ETrue;
+ }
+
+ LOGEXITFN1("CConnMonSession::IsConnectionValid()", result)
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::RemoveObsoleteConnectionParams
+// -----------------------------------------------------------------------------
+//
+void CConnMonSession::RemoveObsoleteConnectionParams()
+ {
+ TInt numSettings = iConnParams.Count();
+ if ( numSettings > 0 )
+ {
+ TInt i( 0 );
+ do
+ {
+ if ( !IsConnectionValid( iConnParams[i].iConnectionId ) )
+ {
+ // Complete any outstanding requests on this connection
+ CompleteDataVolumeRequests(
+ iConnParams[i].iConnectionId,
+ 0,
+ 0,
+ KErrDisconnected );
+
+ CompleteActivityRequests(
+ iConnParams[i].iConnectionId,
+ EFalse,
+ KErrDisconnected );
+
+ // Free resources
+ iConnParams[i].iRequests.Close();
+
+ // Remove the whole entry
+ iConnParams.Remove( i );
+ numSettings = iConnParams.Count();
+ }
+ else
+ {
+ ++i;
+ }
+
+ } while ( i < numSettings );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::CalculateAdjustedThreshold
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::CalculateAdjustedThreshold(
+ const TEventInfo& aEvent,
+ TUint& aAdjustedTh,
+ TUint& aSmallestTh )
+ {
+ TConnSettings settings( 0, 0, 0 );
+ TUint modulo( 0 );
+
+ aAdjustedTh = 0;
+ GetConnectionSettings( aEvent.iConnectionId, settings );
+
+ if ( aEvent.iEventType == EConnMonDownlinkDataThreshold )
+ {
+ iCmServer->CalculateThreshold(
+ aEvent.iConnectionId,
+ EDownlinkThreshold,
+ aSmallestTh );
+
+ if ( aSmallestTh > 0 )
+ {
+ modulo = settings.iDLDataThreshold % aSmallestTh;
+ }
+
+ if ( modulo == 0 )
+ {
+ aAdjustedTh = settings.iDLDataThreshold;
+ }
+ else if ( modulo < aSmallestTh / 2 )
+ {
+ aAdjustedTh = settings.iDLDataThreshold - modulo;
+ }
+ else
+ {
+ aAdjustedTh = settings.iDLDataThreshold + aSmallestTh - modulo;
+ }
+ }
+ else if ( aEvent.iEventType == EConnMonUplinkDataThreshold )
+ {
+ iCmServer->CalculateThreshold(
+ aEvent.iConnectionId,
+ EUplinkThreshold,
+ aSmallestTh );
+
+ if ( aSmallestTh > 0 )
+ {
+ modulo = settings.iULDataThreshold % aSmallestTh;
+ }
+
+ if ( modulo == 0 )
+ {
+ aAdjustedTh = settings.iULDataThreshold;
+ }
+ else if ( modulo < aSmallestTh / 2 )
+ {
+ aAdjustedTh = settings.iULDataThreshold - modulo;
+ }
+ else
+ {
+ aAdjustedTh = settings.iULDataThreshold + aSmallestTh - modulo;
+ }
+ }
+ else
+ {
+ return KErrArgument;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CConnMonSession::AdjustThresholdToAllowedRange
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonSession::AdjustThresholdToAllowedRange(
+ const TInt& aConnId,
+ const TInt& aThresholdType,
+ TUint& aThreshold ) const
+ {
+ LOGENTRFN("CConnMonSession::AdjustThresholdToAllowedRange()")
+ TInt err( KErrNone );
+
+ // Zero value is always allowed
+ if ( aThreshold == 0 )
+ {
+ LOGEXITFN1("CConnMonSession::AdjustThresholdToAllowedRange()", err)
+ return err;
+ }
+
+ switch ( aThresholdType )
+ {
+ case KActivityTimeThreshold:
+ // Already checked for zero earlier
+ if ( aThreshold < KMinimumActivityThreshold )
+ {
+ aThreshold = KMinimumActivityThreshold;
+ }
+ break;
+
+ // Currently same minimum threshold values for both uplink and downlink
+ case KDownlinkDataThreshold:
+ case KUplinkDataThreshold:
+ {
+ TInt bearer( EBearerUnknown );
+ TBearerInfo bearerInfo;
+ TUint minimum( KMinimumDataThreshold );
+
+ // This method gets the bearer only for an internal connection. This is OK
+ // since data volume events are not supported for external connections.
+ iCmServer->Iap()->GetBearer( aConnId, bearer, bearerInfo );
+
+ // Set minimum
+ if ( bearer == EBearerWLAN || bearer == EBearerLAN )
+ {
+ minimum = KMinimumWLANDataThreshold;
+ }
+ else if ( bearer == EBearerGPRS || bearer == EBearerEdgeGPRS )
+ {
+ minimum = KMinimumGPRSDataThreshold;
+ }
+ else if ( bearer == EBearerWCDMA )
+ {
+ minimum = KMinimumWCDMADataThreshold;
+ }
+
+ // Check threshold
+ if ( aThreshold < minimum )
+ {
+ aThreshold = minimum;
+ }
+ }
+ break;
+
+ case KBearerAvailabilityThreshold:
+ case KSignalStrengthThreshold:
+ case KBearerGroupThreshold:
+ // All alowed
+ break;
+ default:
+ LOGIT1("AdjustThresholdToAllowedRange: Illegal value for threshold type %d", aThresholdType)
+ err = KErrNotFound;
+ break;
+ }
+
+ LOGEXITFN1("CConnMonSession::AdjustThresholdToAllowedRange()", err)
+ return err;
+ }
+
+// End-of-file