--- /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