diff -r 000000000000 -r c40eb8fe8501 wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlanbgscanawscomms.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlanbgscanawscomms.cpp Tue Feb 02 02:03:13 2010 +0200 @@ -0,0 +1,433 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This class implements BgScan AWS communication. +* +*/ + +/* +* %version: 2 % +*/ + +#include +#include + +#include "awsinterface.h" +#include "awsenginebase.h" +#include "wlanbgscancommandlistener.h" +#include "wlanbgscancommand.h" +#include "wlanbgscanawscomms.h" +#include "wlanbgscan.h" +#include "am_debug.h" + +/** + * Maximum heap size for AWS thread. + */ +const TInt KMaxHeapSize = 0x10000; + +/** + * BgScan version communicated to AWS. + */ +const TUint KBgScanVersion = 1; + +/** + * Index of the first item in an array. + */ +const TInt KFirstItemIndex = 0; + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::CWlanBgScanAwsComms +// --------------------------------------------------------------------------- +// +CWlanBgScanAwsComms::CWlanBgScanAwsComms( CWlanBgScan& aBgScan ) : + CActive( CActive::EPriorityStandard ), + iBgScan( aBgScan ), + iAws( NULL ), + iAwsImplInfo( NULL ), + iCommandHandler( NULL ), + iAwsVersion( 0 ), + iPendingCommand( EAwsCommandMax ), + iAwsOk( EFalse ) + { + DEBUG( "CWlanBgScanAwsComms::CWlanBgScanAwsComms()" ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::ConstructL +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::ConstructL() + { + DEBUG( "CWlanBgScanAwsComms::ConstructL()" ); + + // create handler for incoming messages from AWS + iCommandHandler = CWlanBgScanCommand::NewL( *this ); + + CActiveScheduler::Add( this ); + + // leaves if no AWS present in system + StartAwsThreadL(); + + DEBUG( "CWlanBgScanAwsComms::ConstructL() - done" ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::NewL +// --------------------------------------------------------------------------- +// +CWlanBgScanAwsComms* CWlanBgScanAwsComms::NewL( CWlanBgScan& aBgScan ) + { + DEBUG( "CWlanBgScanAwsComms::NewL()" ); + CWlanBgScanAwsComms* self = new ( ELeave ) CWlanBgScanAwsComms( aBgScan ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::~CWlanBgScanAwsComms() +// --------------------------------------------------------------------------- +// +CWlanBgScanAwsComms::~CWlanBgScanAwsComms() + { + DEBUG( "CWlanBgScanAwsComms::~CWlanBgScanAwsComms()" ); + + delete iAws; + iAws = NULL; + + delete iAwsImplInfo; + iAwsImplInfo = NULL; + + delete iCommandHandler; + iCommandHandler = NULL; + + iAwsMsgQueue.Close(); + Cancel(); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::CleanupEComArray +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::CleanupEComArray(TAny* aArray) + { + DEBUG( "CWlanBgScanAwsComms::CleanupEComArray()" ); + + ASSERT( aArray ); + + RImplInfoPtrArray *implInfoArray = static_cast ( aArray ); + implInfoArray->ResetAndDestroy(); + implInfoArray->Close(); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::StartAwsThreadL +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::StartAwsThreadL() + { + DEBUG( "CWlanBgScanAwsComms::StartAwsThreadL()" ); + + RImplInfoPtrArray awsImplArray; + TCleanupItem awsImplArrayCleanup( CleanupEComArray, &awsImplArray ); + CleanupStack::PushL( awsImplArrayCleanup ); + + CAwsEngineBase::ListImplementationsL( awsImplArray ); + + if( awsImplArray.Count() == 0 ) + { + DEBUG( "CWlanBgScanAwsComms::StartAwsThreadL() - no AWS implementation found" ); + User::Leave( KErrNotFound ); + } + + // first found AWS implementation will be taken into use + iAwsImplInfo = static_cast( awsImplArray[KFirstItemIndex] ); + awsImplArray.Remove( KFirstItemIndex ); + + CleanupStack::PopAndDestroy( &awsImplArray ); //this causes a call to CleanupEComArray + + DEBUG( "CWlanBgScanAwsComms::StartAwsThreadL() - creating AWS thread" ); + RThread thread; + TInt err = thread.Create( iAwsImplInfo->DisplayName(), + AwsThreadEntryPoint, + KDefaultStackSize, + KMinHeapSize, + KMaxHeapSize, + reinterpret_cast( this ) ); + if( err != KErrNone) + { + DEBUG1( "CWlanBgScanAwsComms::StartAwsThreadL() - error: thread creation failed with error %i", err ); + delete iAwsImplInfo; + iAwsImplInfo = NULL; + User::Leave( err ); + } + + DEBUG( "CWlanBgScanAwsComms::StartAwsThreadL() - Resuming AWS thread" ); + thread.Resume(); + thread.Close(); + + DEBUG( "CWlanBgScanAwsComms::StartAwsThreadL() - done" ); + } + +// ----------------------------------------------------------------------------- +// CWlanBgScanAwsComms::AwsThreadEntryPoint +// +// This method is executing in the context of the AWS thread. +// ----------------------------------------------------------------------------- +// +TInt CWlanBgScanAwsComms::AwsThreadEntryPoint( TAny* aThisPtr ) + { + DEBUG("CWlanBgScanAwsComms::AwsThreadEntryPoint()"); + + CWlanBgScanAwsComms* self = static_cast( aThisPtr ); + + // create cleanup stack + CTrapCleanup* cleanup = CTrapCleanup::New(); + if ( cleanup == NULL ) + { + DEBUG("CWlanBgScanAwsComms::AwsThreadEntryPoint() - error: Cleanup stack creation failed"); + User::Exit( KErrNoMemory ); + } + + __UHEAP_MARK; + + TRAPD( err, self->InstantiateAwsPluginL() ); + if ( err != KErrNone ) + { + DEBUG1("CWlanBgScanAwsComms::AwsThreadEntryPoint() - AWS instantiation leaved with code %i", err); + } + + __UHEAP_MARKEND; + + delete cleanup; + cleanup = NULL; + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CWlanBgScanAwsComms::InstantiateAwsPluginL +// +// This method is executing in the context of the AWS thread. +// ----------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::InstantiateAwsPluginL() + { + DEBUG("CWlanBgScanAwsComms::InstantiateAwsPluginL()"); + + ASSERT( iAwsImplInfo ); + + CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); + CleanupStack::PushL( scheduler ); + CActiveScheduler::Install( scheduler ); + + DEBUG( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - trying to instantiate AWS implementation:" ); + DEBUG1( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - ImplementationUid: 0x%08X", iAwsImplInfo->ImplementationUid().iUid ); +#ifdef _DEBUG + TBuf8 buf8; + buf8.Copy( iAwsImplInfo->DisplayName() ); +#endif + DEBUG1S("CWlanBgScanAwsComms::InstantiateAwsPluginL() - DisplayName: ", buf8.Length(), buf8.Ptr() ); + DEBUG1( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - Version: %i", iAwsImplInfo->Version() ); + DEBUG1S("CWlanBgScanAwsComms::InstantiateAwsPluginL() - DataType: ", iAwsImplInfo->DataType().Length(), iAwsImplInfo->DataType().Ptr() ); + DEBUG1S("CWlanBgScanAwsComms::InstantiateAwsPluginL() - OpaqueData: ", iAwsImplInfo->OpaqueData().Length(), iAwsImplInfo->OpaqueData().Ptr() ); + DEBUG1( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - RomOnly: %i", iAwsImplInfo->RomOnly() ); + DEBUG1( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - RomBased: %i", iAwsImplInfo->RomBased() ); + DEBUG1( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - VendorId: 0x%08X", iAwsImplInfo->VendorId().iId ); + + CAwsEngineBase::TAwsEngineConstructionParameters params = { this, KBgScanVersion, iAwsVersion }; + iAws = CAwsEngineBase::NewL( iAwsImplInfo->ImplementationUid().iUid, ¶ms ); + + DEBUG1( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - AWS instantiated OK, iAwsVersion %u", iAwsVersion ); + iAwsOk = ETrue; + + __e32_memory_barrier(); + DEBUG( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - data members synchronized" ); + + DEBUG( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - starting active scheduler - AWS is now in control of this thread" ); + CActiveScheduler::Start(); + + // Thread execution will stay in CActiveScheduler::Start() until active scheduler is stopped + DEBUG("CWlanBgScanAwsComms::InstantiateAwsPluginL() - active scheduler stopped" ); + + // clean up + delete iAws; + iAws = NULL; + CleanupStack::PopAndDestroy( scheduler ); + + DEBUG( "CWlanBgScanAwsComms::InstantiateAwsPluginL() - exiting..." ); + User::Exit( KErrNone ); + } + +// --------------------------------------------------------------------------- +// From class MAwsBgScanProvider. +// CWlanBgScanAwsComms::SetInterval +// +// This method is executing in the context of the AWS thread. +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::SetInterval( TUint32 aNewInterval, TRequestStatus& aStatus ) + { + DEBUG1( "CWlanBgScanAwsComms::SetInterval() - new interval %u", aNewInterval ); + + iCommandHandler->CommandQueue( CWlanBgScanCommand::ESetInterval, aNewInterval, aStatus ); + + DEBUG( "CWlanBgScanAwsComms::SetInterval() - returning" ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::SendOrQueueAwsCommand +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::SendOrQueueAwsCommand( TAwsMessage& aMessage ) + { + DEBUG1( "CWlanBgScanAwsComms::SendOrQueueAwsCommand( command %u )", aMessage.iCmd ); + + // if a request is pending, queue the new command + if( iStatus.Int() == KRequestPending ) + { + DEBUG( "CWlanBgScanAwsComms::SendOrQueueAwsCommand() - request pending -> queue new command" ); + + // store command to queue + TInt err = iAwsMsgQueue.Append( aMessage ); + if( KErrNone == err ) + { + DEBUG( "CWlanBgScanAwsComms::SendOrQueueAwsCommand() - command queued successfully" ); + } + else + { + DEBUG( "CWlanBgScanAwsComms::SendOrQueueAwsCommand() - command queueing failed" ); + } + return; + } + + SendAwsCommand( aMessage ); + + DEBUG( "CWlanBgScanAwsComms::SendOrQueueAwsCommand() - done" ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::SendAwsCommand +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::SendAwsCommand( TAwsMessage& aMessage ) + { + DEBUG1( "CWlanBgScanAwsComms::SendAwsCommand( command %u )", aMessage.iCmd ); + + if( !iAws ) + { + DEBUG( "CWlanBgScanAwsComms::SendAwsCommand() - error: no AWS present!" ); + ASSERT( 0 ); + return; + } + + DEBUG( "CWlanBgScanAwsComms::SendAwsCommand() - sending command" ); + + switch( aMessage.iCmd ) + { + case EStart: + { + iPendingCommand = EStart; + iAws->Start( iStatus ); + SetActive(); + DEBUG( "CWlanBgScanAwsComms::SendAwsCommand() - EStart command sent" ); + break; + } + case EStop: + { + iPendingCommand = EStop; + iAws->Stop( iStatus ); + SetActive(); + DEBUG( "CWlanBgScanAwsComms::SendAwsCommand() - EStop command sent" ); + break; + } + case ESetPowerSaveMode: + { + iPendingCommand = ESetPowerSaveMode; + iAws->SetPowerSaveMode( static_cast( aMessage.iParameter ), iStatus ); + SetActive(); + DEBUG( "CWlanBgScanAwsComms::SendAwsCommand() - ESetPowerSaveMode command sent" ); + break; + } + default: + { + iPendingCommand = EAwsCommandMax; + DEBUG1( "CWlanBgScanAwsComms::SendAwsCommand() - unknown command %u", aMessage.iCmd ); + ASSERT( 0 ); + } + } + DEBUG( "CWlanBgScanAwsComms::SendAwsCommand() - done" ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::RunL +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::RunL() + { + DEBUG2( "CWlanBgScanAwsComms::RunL() - command: %u, completion status: %d", iPendingCommand, iStatus.Int() ); + + TAwsMessage cmd = { EAwsCommandMax, NULL }; + + // if there are more commands, send the next one + if( iAwsMsgQueue.Count() ) + { + cmd = static_cast ( iAwsMsgQueue[KFirstItemIndex] ); + iAwsMsgQueue.Remove( KFirstItemIndex ); + + SendAwsCommand( cmd ); + } + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::DoCancel +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::DoCancel() + { + DEBUG( "CWlanBgScanAwsComms::DoCancel()" ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::RunError +// --------------------------------------------------------------------------- +// +TInt CWlanBgScanAwsComms::RunError( TInt aError ) + { + DEBUG1( "CWlanBgScanAwsComms::RunError( %d )", aError ); + return aError; + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::DoSetInterval +// --------------------------------------------------------------------------- +// +void CWlanBgScanAwsComms::DoSetInterval( TUint32 aNewInterval ) + { + DEBUG1( "CWlanBgScanAwsComms::DoSetInterval( aNewInterval: %u )", aNewInterval ); + + iBgScan.DoSetInterval( aNewInterval ); + } + +// --------------------------------------------------------------------------- +// CWlanBgScanAwsComms::IsAwsPresent +// --------------------------------------------------------------------------- +// +TBool CWlanBgScanAwsComms::IsAwsPresent() + { + DEBUG1( "CWlanBgScanAwsComms::IsAwsPresent() - returning %d", iAwsOk ); + + return iAwsOk; + }