diff -r e71858845f73 -r e1758cbb96ac systemswstubs/hwrmstubplugins/src/FmtxPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/systemswstubs/hwrmstubplugins/src/FmtxPlugin.cpp Mon Oct 04 00:04:35 2010 +0300 @@ -0,0 +1,528 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Hardware Resource Manager stub plugins fmtx plugin +* implementation. +* +*/ + + + +#include +#include "FmtxPlugin.h" +#include "PluginTimer.h" +#include "Trace.h" + +const TUint32 KFmTxStubPluginFreqMax = 107900; // KHz +const TUint32 KFmTxStubPluginFreqMin = 88100; // KHz +const TUint32 KFmTxStubPluginStepSize = 50; // KHz +const TInt KMaxLengthMarker = 63; + +#ifdef PUBLISH_STATE_INFO +const TUid KPSUidHWResourceNotification = {0x101F7A01}; // HWRM private PS Uid +#endif /* PUBLISH_STATE_INFO */ + + +CFmtxPlugin* CFmtxPlugin::NewL() + { + COMPONENT_TRACE(( _L("CFmtxPlugin::NewL()") )); + + CFmtxPlugin* self = new(ELeave) CFmtxPlugin(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +CFmtxPlugin::~CFmtxPlugin() + { + COMPONENT_TRACE(( _L("CFmtxPlugin::~CFmtxPlugin()") )); + + iTimers.ResetAndDestroy(); +#ifdef PUBLISH_STATE_INFO + iCmdProperty.Close(); + iDataProperty.Close(); +#endif /* PUBLISH_STATE_INFO */ + } + + +CFmtxPlugin::CFmtxPlugin() : iLastCommand(HWRMFmTxCommand::ENoCommandId), + iHwState(HWRMFmTxCommand::EFmTxHwStateOff), + iClearFrequency(KFmTxStubPluginFreqMin) + { + COMPONENT_TRACE(( _L("CFmtxPlugin::CFmtxPlugin()") )); + } + + +void CFmtxPlugin::ConstructL() + { + COMPONENT_TRACE(( _L("CFmtxPlugin::ConstructL") )); + +#ifdef PUBLISH_STATE_INFO + RProperty::Define(KPSUidHWResourceNotification, KHWRMTestFmtxCommand, RProperty::EInt); + RProperty::Define(KPSUidHWResourceNotification, KHWRMTestFmtxDataPckg, RProperty::EByteArray, 512); + iCmdProperty.Attach(KPSUidHWResourceNotification, KHWRMTestFmtxCommand); + iDataProperty.Attach(KPSUidHWResourceNotification, KHWRMTestFmtxDataPckg); +#endif /* PUBLISH_STATE_INFO */ + } + + +TInt CFmtxPlugin::CheckFrequencyWithinRange(TDesC8& aData) + { + HWRMFmTxCommand::TSetFrequencyPackage pckg; + pckg.Copy(aData); + TInt frequency = pckg(); + + if ( frequency < KFmTxStubPluginFreqMin || + frequency > KFmTxStubPluginFreqMax ) + { + COMPONENT_TRACE((_L("CFmtxPlugin::CheckFrequencyWithinRange, frequency %d is out of range"), frequency)); + return KErrArgument; + } + else + { + iFrequency = frequency; + return KErrNone; + } + } + + +void CFmtxPlugin::ProcessCommandL(const TInt aCommandId, + const TUint8 aTransId, + TDesC8& aData) + { + COMPONENT_TRACE((_L("CFmtxPlugin::ProcessCommandL, command: 0x%x, TransId: 0x%x"), aCommandId, aTransId)); + + TInt retVal(KErrNone); + + switch (aCommandId) + { + case HWRMFmTxCommand::ETxOnCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ETxOnCmdId")); + + // check TSetFrequencyPackage param + if ( iHwState != HWRMFmTxCommand::EFmTxHwStateOff ) + { + retVal = KErrInUse; + } + else + { + retVal = CheckFrequencyWithinRange(aData); + } + } + break; + + case HWRMFmTxCommand::ETxOffCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ETxOffCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOff ) + { + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ESetTxFrequencyCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxFrequencyCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // check TSetFrequencyPackage param + retVal = CheckFrequencyWithinRange(aData); + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ETxScanRequestCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ETxScanRequestCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // check TScanRequestPackage param + HWRMFmTxCommand::TScanRequestPackage pckg; + pckg.Copy(aData); + TUint channelsRequested = pckg(); + if( channelsRequested > 10 ) + { + // Should not come here because input verified in client end + retVal = KErrArgument; + } + iChannelsRequested = ( channelsRequested <= 10 ) ? channelsRequested : 10; + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::EGetTxFrequencyRangeCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed EGetTxFrequencyRangeCmdId")); + + // No params to check + } + break; + + case HWRMFmTxCommand::ESetTxRdsPsCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxRdsPsCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // check TRdsPsPackage param + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ESetTxRdsPtyCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxRdsPtyCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // Check TRdsPtyPackage param + HWRMFmTxCommand::TRdsPtyPackage pckg; + pckg.Copy(aData); + TInt programType = pckg(); + const TInt KRdsPtyFirst = 0; + const TInt KRdsPtyLast = 31; + + if( programType < KRdsPtyFirst || programType > KRdsPtyLast ) + { + // Should not come here because input verified in client end + retVal = KErrArgument; + } + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ESetTxRdsPtynCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxRdsPtynCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // Check TRdsPtynPackage param + HWRMFmTxCommand::TRdsPtynPackage pckg; + pckg.Copy(aData); + HWRMFmTxCommand::TRdsPtyn prgTypeName = pckg(); + const TInt KMaxRdsPtynLength = 8; + if( prgTypeName.Length() > KMaxRdsPtynLength ) + { + // Should not come here because input verified in client end + retVal = KErrArgument; + } + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ESetTxRdsMsCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxRdsMsCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // No params to check + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ESetTxRdsLangIdCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxRdsLangIdCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // Check TRdsLangIdPackage param + HWRMFmTxCommand::TRdsLangIdPackage pckg; + pckg.Copy(aData); + TInt languageId = pckg(); + const TInt KRdsLanguageFirst = 0x00; + const TInt KRdsLanguageLast = 0x7F; + + if( languageId < KRdsLanguageFirst || languageId > KRdsLanguageLast ) + { + // Should not come here because input verified in client end + User::Leave(KErrArgument); + } + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::ESetTxRtCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed ESetTxRtCmdId")); + + if ( iHwState == HWRMFmTxCommand::EFmTxHwStateOn ) + { + // Check TRtPackage params + HWRMFmTxCommand::TRtPackage pckg; + pckg.Copy(aData); + HWRMFmTxCommand::TRtData rtData = pckg(); + + if( rtData.iTag1.iContentType > KMaxLengthMarker || rtData.iTag2.iContentType > KMaxLengthMarker || + rtData.iTag1.iLengthMarker > KMaxLengthMarker || rtData.iTag2.iLengthMarker > KMaxLengthMarker ) + { + retVal = KErrArgument; + } + } + else + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + } + break; + + case HWRMFmTxCommand::EClearTxRtCmdId: + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Processed EClearTxRtCmdId")); + + if ( iHwState != HWRMFmTxCommand::EFmTxHwStateOn ) + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: HW isn't ready, iHwState = %d"), iHwState)); + retVal = KErrNotReady; + } + // No params to check + } + break; + + case HWRMFmTxCommand::ENoCommandId: // fall through + default : + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Unknown Command: 0x%x"), aCommandId)); + } + break; + } + + // Check for concurrent requests. Scan request (ETxScanRequestCmdId) may precede + // set frequency (ESetTxFrequencyCmdId), because it is handled as a split command. + if ( iLastCommand != HWRMFmTxCommand::ENoCommandId && + !(iLastCommand == HWRMFmTxCommand::ETxScanRequestCmdId && aCommandId == HWRMFmTxCommand::ESetTxFrequencyCmdId) ) + { + COMPONENT_TRACE(_L("HWRM FmtxPlugin: Not ready due to concurrent command")); + retVal = KErrNotReady; + } + iLastCommand = static_cast(aCommandId); + + TInt timeout(500); // microseconds + + // Increase timeout for scan requests + if (HWRMFmTxCommand::ETxScanRequestCmdId == aCommandId) + { + timeout = 2*1000*1000; // 2 seconds + } + +#ifdef PUBLISH_STATE_INFO + // publish + iCmdProperty.Set(aCommandId); + iDataProperty.Set(aData); +#endif /* PUBLISH_STATE_INFO */ + + // create new timer + CPluginTimer* timer = CPluginTimer::NewL(timeout, iResponseCallback, aCommandId, aTransId, retVal, this); + CleanupStack::PushL(timer); + iTimers.AppendL(timer); + CleanupStack::Pop(timer); + + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Processing command - return"))); + } + + +void CFmtxPlugin::CancelCommandL(const TUint8 aTransId, +#if defined(_DEBUG) && defined(COMPONENT_TRACE_FLAG) + const TInt aCommandId) +#else + const TInt /*aCommandId*/) +#endif + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Cancelling command: 0x%x, TransId: 0x%x"), aCommandId, aTransId)); + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Cancelling command - iTimers.Count(): %d "), iTimers.Count())); + + for( TInt i = 0; i < iTimers.Count(); i++ ) + { + if ( iTimers[i]->TransId() == aTransId ) + { + delete iTimers[i]; + iTimers.Remove(i); + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Cancelling command - Removed command: 0x%x, TransId: 0x%x"), aCommandId, aTransId)); + break; + } + } + + if ( iTimers.Count() == 0 ) + { + // no more commands on-going + iLastCommand = HWRMFmTxCommand::ENoCommandId; + } + } + +void CFmtxPlugin::GenericTimerFired(MHWRMPluginCallback* aService, + TInt aCommandId, + const TUint8 aTransId, + TInt aRetVal) + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: GenericTimerFired (0x%x, 0x%x, %d)"), aCommandId, aTransId, aRetVal)); + + __ASSERT_ALWAYS(aService != NULL, User::Invariant() ); + + TInt err = KErrNone; + + HWRMFmTxCommand::TFmTxHwState tempState = HWRMFmTxCommand::EFmTxHwStateOff; + + switch (aCommandId) + { + case HWRMFmTxCommand::EGetTxFrequencyRangeCmdId: + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Returning freq range"))); + HWRMFmTxCommand::TFrequencyRangeData freqRange; + freqRange.iErrorCode = KErrNone; + freqRange.iMinFrequency = KFmTxStubPluginFreqMin; + freqRange.iMaxFrequency = KFmTxStubPluginFreqMax; + freqRange.iStepSize = KFmTxStubPluginStepSize; + HWRMFmTxCommand::TFrequencyRangePackage freqRangePckg(freqRange); + TRAP(err, aService->ProcessResponseL(aCommandId, aTransId, freqRangePckg)); + } + break; + + case HWRMFmTxCommand::ETxScanRequestCmdId: + { + HWRMFmTxCommand::TScanResponseData scanData; + scanData.iErrorCode = aRetVal; + if ( aRetVal == KErrNone ) + { + if ( (iClearFrequency += KFmTxStubPluginStepSize) > KFmTxStubPluginFreqMax ) + { + iClearFrequency = KFmTxStubPluginFreqMin; + } + scanData.iErrorCode = KErrNone; + scanData.iFrequenciesFound = iChannelsRequested; + TUint32 clearFrequency = iClearFrequency; + for(TInt i=0; i KFmTxStubPluginFreqMax ) + { + clearFrequency = KFmTxStubPluginFreqMin; + } + } + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Returning 1 clear frequency"))); + } + else + { + scanData.iFrequenciesFound = 0; + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Returning 0 clear frequencies"))); + } + HWRMFmTxCommand::TScanResponsePackage scanPckg(scanData); + TRAP(err, aService->ProcessResponseL(aCommandId, aTransId, scanPckg)); + } + break; + + case HWRMFmTxCommand::ETxOnCmdId: // fall through + case HWRMFmTxCommand::ESetTxFrequencyCmdId: + tempState = HWRMFmTxCommand::EFmTxHwStateOn; // fall through + case HWRMFmTxCommand::ETxOffCmdId: + { + if ( aRetVal == KErrNone) + { + iHwState = tempState; + + if ( iStatusIndTransId ) // if request successful, and status indication has been requested + { + // also send frequency/state changed indications for these + COMPONENT_TRACE((_L("HWRM FmtxPlugin: sending status indication"))); + HWRMFmTxCommand::TFmTxStatusData statusData; + statusData.state = tempState; + statusData.frequency = iFrequency; + HWRMFmTxCommand::TStatusIndicationPackage statusIndPckg(statusData); + TInt tempTransId = iStatusIndTransId; // status indication may be reissued immediately... + iStatusIndTransId = 0; // ...so null here first + TRAP(err, aService->ProcessResponseL(HWRMFmTxCommand::ETxStatusIndId, tempTransId, statusIndPckg)); + if ( err != KErrNone ) + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Error sending status indication"))); + } + } + } + } // fall through + + case HWRMFmTxCommand::ESetTxRdsPsCmdId: + case HWRMFmTxCommand::ESetTxRtCmdId: + default : + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Returning error code %d, Command: 0x%x"), aRetVal, aCommandId)); + HWRMFmTxCommand::TErrorCodeResponsePackage retvalPackage(aRetVal); + TRAP(err, aService->ProcessResponseL(aCommandId, aTransId, retvalPackage)); + } + break; + } + + if ( err != KErrNone ) + { + COMPONENT_TRACE((_L("HWRM FmtxPlugin: Error in ProcessResponseL: %d"), err)); + } + + // delete obsolete timers + for( TInt i = (iTimers.Count()-1); i > -1 ; i-- ) + { + if ( !iTimers[i]->IsActive() ) + { + delete iTimers[i]; + iTimers.Remove(i); + COMPONENT_TRACE((_L("HWRM FmtxPlugin: GenericTimerFired - Removed obsolete timer"))); + } + } + + if ( iTimers.Count() == 0 ) + { + // no more commands on-going + iLastCommand = HWRMFmTxCommand::ENoCommandId; + } + }