systemswstubs/hwrmstubplugins/src/FmtxPlugin.cpp
changeset 0 0ce1b5ce9557
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/systemswstubs/hwrmstubplugins/src/FmtxPlugin.cpp	Thu Jan 14 07:14:53 2010 +0200
@@ -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 <hwrmfmtxcommands.h>
+#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<HWRMFmTxCommand::TFmTxCmd>(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<iChannelsRequested; i++)
+    			    {
+    			    scanData.iChannels.Copy(&clearFrequency,i+1);
+    				if ( (clearFrequency += KFmTxStubPluginStepSize) > 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;
+    	}
+    }