coreapplicationuis/ATCmdPlugin/src/atcmdplugin.cpp
changeset 21 c4cbaa4fb734
child 69 dcd4152cfe55
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/coreapplicationuis/ATCmdPlugin/src/atcmdplugin.cpp	Fri Apr 16 15:08:06 2010 +0300
@@ -0,0 +1,1067 @@
+
+/*
+ * Copyright (c) 2008-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 :
+ *
+ */
+
+
+
+// INCLUDES
+#include <hwrmlightdomaincrkeys.h>
+#include <coreapplicationuisdomainpskeys.h>
+#include <hal.h>
+#include <atcmdpluginresource.rsg>
+#include <barsread.h>
+#include <barsc.h>
+#include <bautils.h>
+#include <e32math.h>
+#include <e32base.h>
+#include <eikenv.h>
+#include <apgtask.h>
+#include "debug.h"
+#include "atcmdplugin.h"
+
+// CONSTANTS
+_LIT8( KAtCkpd, "+CKPD" );
+_LIT8( KAtCbklt, "+CBKLT" );
+_LIT8( KCRLF, "\r\n" );
+_LIT8( KAtCtsa, "+CTSA");
+
+const TInt KCustomKeyCodeIdentifier = -1;
+const TInt KGranularity = 10;
+const TInt KTimeMultiplier = 100000;
+const TInt KMicroSeconds = 1000000;
+
+#define REPLY_BUFFER_SIZE 200
+
+// These values are based on testing results.
+// Values less than 2000 causes some times missing key events
+// even all keys are simulated with long commands.
+const TInt KDefaultStrokeDelay = 50000;
+const TInt KDefaultStrokeTime = 10000;
+
+const TInt KLightTarget = CHWRMLight::EPrimaryDisplayAndKeyboard;
+
+_LIT8( KParameterSeparator, "," );
+_LIT8( Kok, "\r\nOK\r\n");
+_LIT8( KCmeErrorNotSupported, "\r\n+CME ERROR: 4\r\n");
+_LIT8( KTestCommand, "=?" );
+_LIT8( KReadCommand, "?" );
+_LIT8( KCbkltTestCommandResp, ":(0,1,2)" );
+_LIT8( KCkpdTestCommandResp,  ":(GSM)" );
+_LIT8( KCtsaTestCommandResp, ":(0,1,2),(width),(height)" );
+_LIT( KFileName, "\\resource\\apps\\atcmdpluginresource.rsc" );
+
+
+// ============================= MEMBER FUNCTIONS =============================
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::NewL
+// 2-phased constructor
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+CATCmdPluginEcom* CATCmdPluginEcom::NewL()
+    {
+    CATCmdPluginEcom* self = new (ELeave) CATCmdPluginEcom();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::CATCmdPluginEcom
+// Constructor
+// ----------------------------------------------------------------------------
+//
+CATCmdPluginEcom::CATCmdPluginEcom() 
+    : CATExtPluginBase()
+    {
+    TRACE_FUNC
+    }
+     
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::ConstructL
+// Constructor
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::ConstructL()
+    {
+    TRACE_FUNC
+	
+    LEAVE_IF_ERROR( iWsSession.Connect() );
+    iCkpdCmdArray = new (ELeave) CArrayFixFlat<TATCkpdCmd>( KGranularity );
+    
+    iKpdTimer = new ( ELeave ) CATCmdTimer( *this, ECmdCkpd );
+	iKpdTimer->ConstructL();
+	
+    iBkltTimer = new ( ELeave ) CATCmdTimer( *this, ECmdCbklt );
+    iBkltTimer->ConstructL();
+    
+    iKeepAliveTimer = new ( ELeave ) CATCmdTimer( *this, EKeepAlive );
+    iKeepAliveTimer->ConstructL();
+
+	
+    LoadResourcesL();
+   	}
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::::LoadResourcesL
+// Load resources
+// (may leave)
+// Status : Approved
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::LoadResourcesL()
+    {
+    TRACE_FUNC_ENTRY
+
+    RFs fs;
+    CleanupClosePushL( fs );
+
+    TFileName fileName;
+    fileName.Copy( KFileName );
+    User::LeaveIfError( fs.Connect() );
+    BaflUtils::NearestLanguageFile( fs, fileName );
+
+    RResourceFile resourceFile;
+    CleanupClosePushL( resourceFile );
+    resourceFile.OpenL( fs, fileName );
+    resourceFile.ConfirmSignatureL();
+
+    HBufC8* buf8 = resourceFile.AllocReadLC( R_ATCMDPLUGIN_TRANSLATIONTABLE );
+    
+    TResourceReader reader;
+    reader.SetBuffer( buf8 );
+    
+    TInt count = reader.ReadInt16(); // array count
+    iTranslations = new ( ELeave ) CArrayPtrFlat<CATCmdTranslation>( count );
+
+    while ( count-- )
+        {
+        const TInt code = reader.ReadInt32(); 
+
+        HBufC8* param = reader.ReadHBufC8L(); 
+        CleanupStack::PushL( param );
+        CATCmdTranslation* t = new (ELeave) CATCmdTranslation( *param, code );
+        CleanupStack::Pop( param ); // transfer ownership
+
+        CleanupStack::PushL( t );
+        iTranslations->AppendL( t );
+        CleanupStack::Pop( t ); // transfer ownership
+        }
+
+    CleanupStack::PopAndDestroy( 3 ); // resourceFile, fs, buf8
+
+    TRACE_FUNC_EXIT
+    }
+
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::~CATCmdPluginEcom
+// C++ Destructor
+// ----------------------------------------------------------------------------
+//
+CATCmdPluginEcom::~CATCmdPluginEcom()
+	{
+	TRACE_FUNC
+	
+    if(iKpdTimer)
+        {
+        iKpdTimer->Cancel();
+        delete iKpdTimer;
+        }	    
+    if(iBkltTimer)
+        {
+        iBkltTimer->Cancel();
+        delete iBkltTimer;
+        }
+    if(iKeepAliveTimer)
+        {
+        iKeepAliveTimer->Cancel();
+        delete iKeepAliveTimer;
+        }
+    if ( iTranslations)
+        {
+        iTranslations->ResetAndDestroy();
+        delete iTranslations;
+        }    
+    if ( iCkpdCmdArray)
+        {
+        iCkpdCmdArray->Reset();
+        delete iCkpdCmdArray;
+        }
+    iWsSession.Close();
+	}
+
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::HandleCommand
+// Handle given command
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::HandleCommand( const TDesC8& aCmd, RBuf8& aReply, TBool /* aReplyNeeded  */)
+	{
+	TRACE_FUNC_ENTRY
+	aReply.Create(REPLY_BUFFER_SIZE);
+	aReply.Zero();
+	iReplyBuf = &aReply;
+	
+	if ( IsCommandSupported( aCmd ) )
+	    {
+	    	
+		TRAPD( err, HandleCommandL( aCmd ) );
+
+		if ( err )
+			{
+			iReplyBuf->Append( KCmeErrorNotSupported ); 
+			}
+		else
+			{
+			if(iReplyBuf->Length() == 0)
+				{
+				iReplyBuf->Append( Kok );
+				} 
+			}
+		HandleCommandCompleted( KErrNone,EReplyTypeOk );      
+		}
+    TRACE_FUNC_EXIT
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::HandleCommandL
+// Handle given command
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::HandleCommandL( const TDesC8& aCmd )
+	{
+    // Verify command
+    TInt offset;
+    HBufC8* cmd = aCmd.AllocLC();
+//    CleanupStack:: PushL(cmd);
+    TPtr8 ptr = cmd->Des();
+
+    ptr.Trim();
+    TPtrC8 cptr;
+
+    if ( ( offset = ptr.FindF(KAtCkpd) ) >= 0 )
+        {
+        cptr.Set( ptr.Mid( offset + KAtCkpd().Length() ) );         
+        HandleCkpdCommandL( cptr );
+        }
+    else if ( ( offset = ptr.FindF(KAtCbklt) ) >= 0 ) 
+        {
+        cptr.Set( ptr.Mid( offset + KAtCbklt().Length() ) );
+        HandleCbkltCommandL( cptr );
+        }
+    else if ( ( offset = ptr.FindF(KAtCtsa) ) >= 0 )
+    	{
+    	cptr.Set( ptr.Mid( offset + KAtCtsa().Length() ) );
+    	HandleCtsaCommandL( cptr );
+    	} 
+    CleanupStack::PopAndDestroy( cmd );
+    }    
+
+// -------------------------
+//  HandleCtsaCommandL
+//
+// -------------------------
+
+void CATCmdPluginEcom::HandleCtsaCommandL( const TDesC8& aCmd )
+    {
+    
+    if ( aCmd.Compare( KTestCommand ) == 0 )
+        {
+        // Test command just returns "OK"        
+        iReplyBuf->Append( KCRLF );
+        iReplyBuf->Append( KAtCtsa );
+        iReplyBuf->Append( KCtsaTestCommandResp );
+        iReplyBuf->Append( KCRLF );
+        TRACE_FUNC_EXIT
+        return;
+        }  
+    
+    // Check boundary condition
+	if ( ( aCmd.Length() < 6 ) || ( aCmd[2] !=  ',' ))
+	    {
+	    // Command Syntax Error
+	    User::Leave( KErrNotSupported );           
+	    } 	
+ 	TInt   pos=0;
+ 	TInt8  actionValue = aCmd[1] - '0';
+ 	TInt16 xCoordinateValue = 0;
+ 	TInt16 yCoordinateValue = 0;
+ 	TInt16 commandLen = aCmd.Length();  
+ 	 
+ 	
+ 	if( actionValue < 0 || actionValue > 4 )
+ 	    {
+ 	    // Command Syntax Error          
+ 	    User::Leave( KErrNotSupported );                  
+ 	    }
+ 	
+ 	pos=3;  // X Cordinate starts from 3d character
+ 	
+ 	CWsScreenDevice *scrnDevPointer = new(ELeave) CWsScreenDevice(iWsSession);
+ 	TSize coordinateSize;
+ 	
+	scrnDevPointer->Construct();
+ 	coordinateSize = scrnDevPointer->SizeInPixels();  
+ 	delete scrnDevPointer;
+ 	
+	while(pos < commandLen)
+ 	    {
+ 	    if((aCmd[pos] >=  '0') && (aCmd[pos] <=  '9'))
+ 	        {
+ 	        xCoordinateValue *= 10;
+ 	        xCoordinateValue += aCmd[pos] - '0';
+ 	        pos++;
+ 	        if(xCoordinateValue > coordinateSize.iWidth )
+ 	            {
+ 	            // Command Syntax Error            
+ 	            User::Leave( KErrNotSupported );           
+ 	            }
+ 	        }
+ 	    else if((aCmd[pos] ==  ',') && pos > 3 )
+            {
+            pos++;
+            break;
+            }
+ 	    else
+ 	        {
+ 	        // Command Syntax Error            
+ 	        User::Leave( KErrNotSupported );             
+ 	        } 	    
+ 	    }
+	if(pos == commandLen)	
+		{
+		// Command of type =0,100        /* Command Syntax Error */
+ 	    User::Leave( KErrNotSupported );  
+		}
+ 	while(pos < commandLen)
+ 	    {
+ 	    if((aCmd[pos] >=  '0') && (aCmd[pos] <=  '9'))
+ 	        {
+ 	        yCoordinateValue *= 10;
+ 	        yCoordinateValue += aCmd[pos] - '0';
+ 	        pos++;
+			if(yCoordinateValue > coordinateSize.iHeight)
+ 	            {
+ 	            // Command Syntax Error            
+ 	            User::Leave( KErrNotSupported );           
+ 	            }
+ 	        }
+ 	    else
+ 	        {
+ 	        // Command Syntax Error            
+ 	        User::Leave( KErrNotSupported );             
+ 	        }       
+ 	    }
+ 	
+ 	TRawEvent rawEvent;
+	switch(actionValue)
+		{
+		case 0:  // Release pointer event
+		    {
+			rawEvent.Set( TRawEvent::EButton1Up, xCoordinateValue, yCoordinateValue);
+			iWsSession.SimulateRawEvent(rawEvent);
+			iWsSession.Flush();
+			break;
+			}
+		case 1:   // Depress pointer event
+			{
+			rawEvent.Set( TRawEvent::EButton1Down, xCoordinateValue, yCoordinateValue);
+			iWsSession.SimulateRawEvent(rawEvent);
+			iWsSession.Flush();
+			break;
+			}
+		case 2:   // Single tap pointer event
+			{
+			rawEvent.Set( TRawEvent::EButton1Down, xCoordinateValue, yCoordinateValue);
+			iWsSession.SimulateRawEvent(rawEvent);
+			rawEvent.Set( TRawEvent::EButton1Up, xCoordinateValue+1, yCoordinateValue+1);
+			iWsSession.SimulateRawEvent(rawEvent);
+			iWsSession.Flush();
+			break;
+			}
+		case 3:   // Double tap pointer event
+			{
+			rawEvent.Set( TRawEvent::EButton1Down, xCoordinateValue, yCoordinateValue);
+			iWsSession.SimulateRawEvent(rawEvent);
+			rawEvent.Set( TRawEvent::EButton1Up, xCoordinateValue+1, yCoordinateValue+1);
+			iWsSession.SimulateRawEvent(rawEvent);
+			rawEvent.Set( TRawEvent::EButton1Down, xCoordinateValue, yCoordinateValue);
+			iWsSession.SimulateRawEvent(rawEvent);
+			rawEvent.Set( TRawEvent::EButton1Up, xCoordinateValue+1, yCoordinateValue+1);
+			iWsSession.SimulateRawEvent(rawEvent);
+			iWsSession.Flush();
+			break;
+			}
+		}
+	}     
+    
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::HandleCkpdCommandL
+// Handle CKPD command
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::HandleCkpdCommandL( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+    TBool commandVerified(EFalse);
+    TInt strokeTime = 0;
+    TInt strokeDelay = 0;
+    
+    if ( aCmd.Compare( KTestCommand ) == 0 )
+        {
+        iReplyBuf->Append( KCRLF );
+        iReplyBuf->Append( KAtCkpd );
+        iReplyBuf->Append( KCkpdTestCommandResp );
+        iReplyBuf->Append( KCRLF );
+        TRACE_FUNC_EXIT
+        return;
+        }
+
+    CArrayFix<TATCkpdCmd>* ckpdCmds = 
+        new (ELeave) CArrayFixFlat<TATCkpdCmd>( KGranularity );
+    CleanupStack::PushL( ckpdCmds );
+    
+    // Check that keys are defined
+    if (  aCmd.Length() <= 1  )
+        {
+        // Command Syntax Error          
+        User::Leave( KErrNotSupported );           
+        }
+
+    // Go through keys
+    TBuf8<2> key;
+    for (TInt i = 1 ; i < aCmd.Length(); i++ )
+        {
+        key.Copy(&aCmd[i],1);
+
+        // Go through translation table for every character
+        for ( TInt j = 0; j < iTranslations->Count(); j++ )
+            {
+            CATCmdTranslation& translation = *iTranslations->At( j );
+            if ( key.CompareF( translation.Param() ) == 0 )
+                {
+                // Check if key is escape character for manufacturer specific keys
+                if ( translation.Code() == KCustomKeyCodeIdentifier )
+                    {
+                    // Read next key to form key combination
+                    i++;
+                    
+                    // Check that there are key after escape character
+                    if ( i >= aCmd.Length() )
+                        {
+                        TRACE_INFO(( _L( "INFO: invalid manufacturer specific key" ) ))            
+                        // Not handled
+                        User::Leave( KErrNotSupported );           
+                        }
+
+                    if ( key.Length() < key.MaxLength() )
+                        {
+                        key.Append(aCmd[i]);
+                        }
+
+                    // Start looping again for looking keycombination
+                    // from translation table
+                    j = 0;
+                    }
+                else
+                    {
+                    // Command verified
+                    commandVerified = ETrue;
+
+                    if ( translation.Code() != EKeyNull )
+                        {
+                        TATCkpdCmd cmd;
+                        cmd.iCode = translation.Code();
+                        ckpdCmds->AppendL( cmd );
+                        }
+
+                    break;
+                    }
+                }
+            }
+
+        if (!commandVerified)
+            {
+            // Check if character is parameter separator
+            if ( key.Compare( KParameterSeparator ) == 0 )
+                {
+                i++;
+
+                if ( i > aCmd.Length() )
+                    {
+                    TRACE_ERROR(( _L( "ERROR: invalid stroke time parameter" ) ))
+
+                    // Not handled
+                    User::Leave( KErrNotSupported );
+                    }
+
+                ParseParametersL(
+                        aCmd.Right(aCmd.Length()-i),
+                        strokeTime,
+                        strokeDelay);
+
+                strokeTime *= KTimeMultiplier;
+                strokeDelay *= KTimeMultiplier;
+                
+                break;
+                }
+            else
+                {
+                TRACE_ERROR(( _L8( "ERROR: Command %S not supported" ), &key ))
+
+                // Not handled
+                User::Leave( KErrNotSupported );
+                }
+            }
+
+        commandVerified = EFalse;
+        }
+
+    // Set default stroke time and delay if those are not set with parameters or
+    // parameter value have been zero. If values are not greater than ~2ms there
+    // is possibility to loose key events with long commands even all keys are
+    // simulated by atcmdplugin
+    if ( !strokeTime )
+        {
+        strokeTime = KDefaultStrokeTime;
+        }
+
+    if ( !strokeDelay )
+        {
+        strokeDelay = KDefaultStrokeDelay;
+        }
+
+    // Append commands to command array
+    for ( TInt count = 0; count < ckpdCmds->Count(); count++ )
+        {
+        TATCkpdCmd cmd = ckpdCmds->At(count);
+        cmd.iStrokeTime = strokeTime;
+        cmd.iStrokeDelay = strokeDelay;
+        
+        iCkpdCmdArray->AppendL( cmd );
+        }
+
+    CleanupStack::PopAndDestroy(ckpdCmds);
+
+    SendKeyL();
+    
+    TRACE_FUNC_EXIT
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::HandleCbkltCommandL
+// Handle CKPD command
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::HandleCbkltCommandL( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+
+         
+    if ( aCmd.Compare( KTestCommand ) == 0 )
+        {
+        iReplyBuf->Append( KCRLF );
+        iReplyBuf->Append( KAtCbklt );
+        iReplyBuf->Append( KCbkltTestCommandResp );
+        iReplyBuf->Append( KCRLF );
+        TRACE_FUNC_EXIT
+        return;
+        }
+		
+	if(iLightStatus != ELightOnWithDuration)
+		{
+		iLight = CHWRMLight::NewL( this );
+	
+		iLightStatus = 
+			( iLight->LightStatus( KLightTarget ) == CHWRMLight::ELightOff )?
+			ELightOff : ELightOn;   
+		delete iLight;		
+		}
+
+    if ( aCmd.Compare( KReadCommand ) == 0 )
+        {
+        iReplyBuf->Append( KCRLF );
+        iReplyBuf->Append( KAtCbklt );
+        iReplyBuf->Append( ':' );
+        iReplyBuf->Append( ' ' );
+        iReplyBuf->AppendNum( iLightStatus );
+        if ( iLightStatus == ELightOnWithDuration )
+            {
+            iReplyBuf->Append( ',' );
+            iReplyBuf->AppendNum( iDuration );
+            }
+        iReplyBuf->Append( KCRLF );
+        TRACE_FUNC_EXIT
+        return;
+        }
+
+    if ( aCmd.Length() <= 1 )
+        {
+        // Command Syntax Error        
+        User::Leave( KErrNotSupported );
+        }
+
+    switch ( aCmd[ 1 ] )
+        {
+        case '0':
+            {
+            if ( aCmd.Length() == 2 )
+                {
+                iKeepAliveTimer->Cancel();
+                DisableBackLight();
+                iLightStatus = ELightOff;
+                }
+            else
+                {
+                //if the command is too long it means that is incorrect
+                User::Leave( KErrNotSupported );
+                }
+            break;
+            }
+        case '1':
+            {
+            if ( ( aCmd.Length() > 3 ) && ( aCmd[ 2 ] == ',' ) )
+                {                
+                TInt pos = 3;
+                TInt commandLen = aCmd.Length();
+                iDuration = 0;
+                while(pos < commandLen)
+                        {
+                        if((aCmd[pos] >=  '0') && (aCmd[pos] <=  '9'))
+                            {
+                            iDuration *= 10;
+                            iDuration += aCmd[pos] - '0';
+                            pos++;
+                            }
+                        else
+                            {
+                            User::Leave( KErrNotSupported );             
+                            }
+                        }
+                iBkltTimer->Cancel();
+                iBkltTimer->After( iDuration * KMicroSeconds );
+                EnableBackLight();
+                if ( !iKeepAliveTimer->IsActive() )
+                     {
+                     iKeepAliveTimer->After( 2000000 );
+                     }
+                iLightStatus = ELightOnWithDuration;
+                }
+            else
+                {
+                //the command is wrong
+                User::Leave( KErrNotSupported );
+                }
+            break;
+            }
+        case '2':
+            {
+            if ( aCmd.Length() == 2 )
+                {
+                iBkltTimer->Cancel();
+                EnableBackLight();
+                if ( !iKeepAliveTimer->IsActive() )
+                    {
+                    iKeepAliveTimer->After( 2000000 );
+                    }
+                iLightStatus = ELightOn;
+                }
+            else
+                {
+                //if the command is too long it means that is incorrect
+                User::Leave( KErrNotSupported );
+                }
+            break;
+            }
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            }
+        }
+    TRACE_FUNC_EXIT
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::EnableBackLight()
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::EnableBackLight()
+	{
+	TRACE_FUNC
+	RProperty::Set( KPSUidCoreApplicationUIs, KLightsATCForcedLightsOn, EForcedLightsOn );
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::DisableBackLight()
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::DisableBackLight()
+	{
+	TRACE_FUNC
+    RProperty::Set( KPSUidCoreApplicationUIs, KLightsATCForcedLightsOn, EForcedLightsOff );
+    }
+
+// -----------------------------------------------------------------------------
+// CATCmdPluginEcom::LightStatusChanged()
+// -----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::LightStatusChanged( TInt /*aTarget*/, CHWRMLight::TLightStatus /*aStatus*/ )
+	{
+	//TRACE_STATE(( _L( "** LightStatusChanged %d, %d" ), aTarget, aStatus ))
+  }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::IsCommandSupported
+// -
+// ----------------------------------------------------------------------------
+//
+TBool CATCmdPluginEcom::IsCommandSupported( const TDesC8& aCmd )
+    {
+    TRACE_FUNC
+    TBool ret(EFalse);
+    
+    if ( aCmd != KNullDesC8 && ( aCmd.FindF(KAtCkpd) >= 0 || 
+                                 aCmd.FindF(KAtCbklt) >= 0 || aCmd.FindF(KAtCtsa) >= 0 ))
+        {
+        ret = ETrue;
+        }
+    return ret;
+    }
+
+// CATCmdPluginEcom::ParseParameterL
+// -
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::ParseParametersL( 
+        const TDesC8& aCmd,
+        TInt& aStrokeTime,
+        TInt& aStrokeDelay )
+    {
+    TRACE_FUNC_ENTRY
+    
+    TInt i(0);
+    
+    if ( !aCmd.Length() )
+        {
+        TRACE_ERROR(( _L( "ERROR: invalid stroke time parameter" ) ))            
+        // Not handled
+        User::Leave( KErrNotSupported );           
+        }
+
+
+    // Parse stroke time parameter
+    TBuf8<3> strokeTimeBuf;
+
+    // Go through command until end or parameter separator is reached
+    for ( ; i < aCmd.Length(); i++ )
+        {
+        if ( aCmd[i] >= '0' && aCmd[i] <= '9' )
+            {
+            strokeTimeBuf.Append(aCmd[i]);
+            continue;
+            }
+        else if ( aCmd[i] == ',' || aCmd[i] == '\r' || aCmd[i] == '\n' )
+            {
+            i++;
+            break;
+            }
+        else
+            {
+            TRACE_ERROR(( _L( "ERROR: invalid stroke time parameter" ) ))
+
+            // Not handled
+            User::Leave( KErrNotSupported );   
+            }
+        }
+
+    TLex8 strokeTimeLex( strokeTimeBuf );          
+    strokeTimeLex.Val( aStrokeTime );
+
+    // Verify parsed parameter
+    if ( aStrokeTime < 0 || aStrokeTime > 255 )
+        {
+        TRACE_ERROR(( _L( "ERROR: invalid stroke time parameter" ) ))
+
+        // Not handled
+        User::Leave( KErrNotSupported );
+        }
+
+
+    // Parse stroke delay parameter
+    TBuf8<3> strokeDelayBuf;
+
+    for ( ; i < aCmd.Length(); i++ )
+        {
+        if ( aCmd[i] >= '0' && aCmd[i] <= '9' )
+            {
+            strokeDelayBuf.Append(aCmd[i]);
+            continue;
+            }
+        else if ( aCmd[i] == ',' || aCmd[i] == '\r' || aCmd[i] == '\n' )
+            {
+            break;
+            }
+        else
+            {
+            TRACE_ERROR(( _L( "ERROR: invalid stroke delay parameter" ) ))
+
+            // Not handled
+            User::Leave( KErrNotSupported );   
+            }
+        }
+
+    TLex8 strokeDelayLex( strokeDelayBuf );          
+    strokeDelayLex.Val( aStrokeDelay );
+
+    if ( aStrokeDelay < 0 || aStrokeDelay > 255 )
+        {
+        TRACE_ERROR(( _L( "ERROR: invalid stroke delay parameter" ) ))
+
+        // Not handled
+        User::Leave( KErrNotSupported );
+        }
+    
+    TRACE_FUNC_EXIT
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::SendKeyL
+// -
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::SendKeyL()
+	{
+	TRACE_FUNC
+
+	if ( !iKpdTimer->IsActive() )
+	    {
+	    const TInt count = iCkpdCmdArray->Count();
+	    if ( count )
+	        {
+            TATCkpdCmd cmd = iCkpdCmdArray->At(0);
+            TKeyEvent key;
+            key.iScanCode = cmd.iCode;
+            key.iCode = 0;
+            key.iRepeats = 0;
+            
+            TTimeIntervalMicroSeconds32 strokeTime = cmd.iStrokeTime;
+            TTimeIntervalMicroSeconds32 strokeDelay = cmd.iStrokeDelay;
+
+            TRACE_INFO(( _L( "   Scancode:%d, stroke time:%d, stroke delay: %d" ),
+                        key.iScanCode, strokeTime.Int(), strokeDelay.Int() ))
+
+            if ( iLastEvent == EEventNull || iLastEvent == EEventKeyUp)
+                {
+                SimulateRawEventL( key, EEventKeyDown );                    
+                
+                if ( strokeTime.Int() > 0)
+                    {
+                    iKpdTimer->After( strokeTime );
+                    return;
+                    }
+                }
+            
+            if ( iLastEvent == EEventKeyDown || iLastEvent == EEventKey )
+                {
+                SimulateRawEventL( key, EEventKeyUp );
+
+                iCkpdCmdArray->Delete( 0 );
+                
+                if ( strokeDelay.Int() > 0 && iCkpdCmdArray->Count() > 0 )
+                    {
+                    iKpdTimer->After( strokeDelay );
+                    return;
+                    }
+                else
+                    {
+                    SendNextKeyL();
+                    }
+                }
+	        }
+	    }
+	}
+
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::SendNextKeyL
+// -
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::SendNextKeyL()
+    {
+    TRACE_FUNC
+
+    const TInt count = iCkpdCmdArray->Count();
+    if ( count )
+        {
+        SendKeyL();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::TimerExpiredL
+// -
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::TimerExpiredL( TInt aRelatedCommand )
+	{
+	TRACE_FUNC
+	
+	if( aRelatedCommand == ECmdCkpd )
+		{
+        SendNextKeyL();
+		}
+	else if ( aRelatedCommand == ECmdCbklt )
+	    {
+	    DisableBackLight();
+	    iLightStatus = ELightOff;
+	    iKeepAliveTimer->Cancel();
+	    }
+	else
+	    {
+	    User::ResetInactivityTime();
+	    iKeepAliveTimer->After( 2000000 );
+	    }
+	}		
+    
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::SimulateRawEventL
+// -
+// (may leave)
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::SimulateRawEventL( TKeyEvent& aKey, TEventCode aEvent )   
+    {
+    TRACE_FUNC
+
+    TRawEvent rawEvent;
+    TRawEvent::TType rawType( TRawEvent::ENone );
+    switch ( aEvent )
+        {
+        case EEventKeyUp:
+            rawType = TRawEvent::EKeyUp;
+            break;
+        case EEventKeyDown:
+            rawType = TRawEvent::EKeyDown;
+            break;
+        default:
+            break;
+        }
+
+    if ( rawType != TRawEvent::ENone )
+        {
+        rawEvent.Set( rawType, aKey.iScanCode );
+        iWsSession.SimulateRawEvent( rawEvent );
+        iWsSession.Flush();
+        }
+
+    iLastEvent = aEvent;
+    }
+
+// ========================= OTHER EXPORTED FUNCTIONS =========================
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::CATCmdTimer::CATCmdTimer
+// C++Constructor
+// ----------------------------------------------------------------------------
+//
+CATCmdPluginEcom::CATCmdTimer::CATCmdTimer( MATCmdTimer& aObserver, 
+                                         TInt aRelatedCommand )
+    : CTimer( EPriorityStandard ),
+      iObserver( aObserver ),
+      iRelatedCommand( aRelatedCommand )
+    {
+    TRACE_FUNC
+
+    CActiveScheduler::Add( this );
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::CATCmdTimer::ConstructL
+// 2nd phase constructor
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::CATCmdTimer::ConstructL()
+    {
+    TRACE_FUNC
+    CTimer::ConstructL();
+    }
+
+// ----------------------------------------------------------------------------
+// CATCmdPluginEcom::CATCmdTimer::RunL
+// Timer callback
+// ----------------------------------------------------------------------------
+//
+void CATCmdPluginEcom::CATCmdTimer::RunL()
+    {
+    TRACE_FUNC
+
+    const TInt err = iStatus.Int();
+    if ( err != KErrCancel )
+        {
+        iObserver.TimerExpiredL( iRelatedCommand );
+        }
+    }
+
+
+void CATCmdPluginEcom::ReportConnectionName( const TDesC8&  /*  aName  */)
+    {
+    
+    }
+void CATCmdPluginEcom::HandleCommandCancel()
+    {
+    
+    }
+void CATCmdPluginEcom::ReportExternalHandleCommandError()
+    {
+    
+    }
+void CATCmdPluginEcom::ReportNvramStatusChange( const TDesC8& /*  aNvram  */)
+    {
+    
+    }
+void CATCmdPluginEcom::ReceiveUnsolicitedResultCancel()
+    {
+    
+    }
+void CATCmdPluginEcom::ReceiveUnsolicitedResult()
+    {
+    
+    }
+TInt CATCmdPluginEcom::GetNextPartOfReply( RBuf8& /* aNextReply  */)
+    {
+    return KErrNone;
+    }
+TInt CATCmdPluginEcom::NextReplyPartLength()
+    {
+    return KErrNone;
+    }
+
+
+//  End of File