diff -r 000000000000 -r c3e98f10fcf4 localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp Mon Jan 18 21:03:15 2010 +0200 @@ -0,0 +1,1652 @@ +/* +* 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 "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: AT command handler and notifier +* +*/ + +/* + * Points to consider: + * - Each of the AT commands sent to ATEXT are converted to upper case form. + * Thus the ATEXT plugins don't need to check for case. The conversion to + * upper case form stops when carriage return or '=' character is found. + */ + +/* + * The AT command handling is splitted to two parts on high level: + * 1) Splitter: splitting the sub-commands in a command line to multiple ones + * for ATEXT to process. + * 2) Combiner: combining the replies coming from ATEXT using a filter + * (the filter categories are explained in DunAtCmdPusher.cpp) + */ + +#include "DunAtCmdHandler.h" +#include "DunAtUrcHandler.h" +#include "DunDownstream.h" +#include "DunDebug.h" + +const TInt8 KDunCancel = 24; + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +EXPORT_C CDunAtCmdHandler* CDunAtCmdHandler::NewL( + MDunAtCmdStatusReporter* aUpstream, + MDunStreamManipulator* aDownstream, + const TDesC8* aConnectionName ) + { + CDunAtCmdHandler* self = new (ELeave) CDunAtCmdHandler( + aUpstream, + aDownstream, + aConnectionName ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CDunAtCmdHandler::~CDunAtCmdHandler() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::~CDunAtCmdHandler()") )); + ResetData(); + FTRACE(FPrint( _L("CDunAtCmdHandler::~CDunAtCmdHandler() complete") )); + } + +// --------------------------------------------------------------------------- +// Resets data to initial values +// --------------------------------------------------------------------------- +// +EXPORT_C void CDunAtCmdHandler::ResetData() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ResetData()") )); + // APIs affecting this: + // IssueRequest() + Stop(); + // NewL() + DeletePluginHandlers(); + delete iNvramListen; + iNvramListen = NULL; + delete iModeListen; + iModeListen = NULL; + delete iEcomListen; + iEcomListen = NULL; + if ( iAtCmdExtCommon.Handle() ) + { + iAtCmdExtCommon.SynchronousClose(); + iAtCmdExtCommon.Close(); + } + if ( iAtCmdExt.Handle() ) + { + iAtCmdExt.SynchronousClose(); + iAtCmdExt.Close(); + } + iSpecials.ResetAndDestroy(); + iSpecials.Close(); + // AddCmdModeCallback() + iCmdCallbacks.Close(); + // Internal + Initialize(); + FTRACE(FPrint( _L("CDunAtCmdHandler::ResetData() complete") )); + } + +// --------------------------------------------------------------------------- +// Adds callback for command mode notification +// The callback will be called when command mode starts or ends +// --------------------------------------------------------------------------- +// +EXPORT_C TInt CDunAtCmdHandler::AddCmdModeCallback( MDunCmdModeMonitor* aCallback ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback()" ) )); + if ( !aCallback ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (aCallback) not initialized!" ) )); + return KErrGeneral; + } + TInt retTemp = iCmdCallbacks.Find( aCallback ); + if ( retTemp != KErrNotFound ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (already exists) complete" ) )); + return KErrAlreadyExists; + } + retTemp = iCmdCallbacks.Append( aCallback ); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (append failed!) complete" ) )); + return retTemp; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() complete" ) )); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Parses an AT command +// --------------------------------------------------------------------------- +// +EXPORT_C TInt CDunAtCmdHandler::ParseCommand( TDesC8& aCommand, + TBool& aPartialInput ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") )); + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") )); + FTRACE(FPrintRaw(aCommand) ); + iCommand = &aCommand; + // Manage partial AT command + TBool needsCarriage = ETrue; + TBool okToExit = ManagePartialCommand( aCommand, needsCarriage ); + if ( okToExit ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (ok to exit) complete") )); + aPartialInput = ETrue; + return KErrNone; + } + if ( iHandleState != EDunStateIdle ) + { + aPartialInput = EFalse; + ResetParseBuffers(); + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not ready) complete") )); + return KErrNotReady; + } + TBool pushStarted = HandleASlashCommand(); + if ( pushStarted ) + { + // Note: return here with "partial input" status to fool CDunUpstream + // into reissuing the read request. The AT command has not really + // started yet so this is necessary. + aPartialInput = ETrue; + ResetParseBuffers(); + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (A/) complete") )); + return KErrNone; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received total:") )); + FTRACE(FPrintRaw(iInputBuffer) ); + iHandleState = EDunStateAtCmdHandling; + iUpstream->NotifyAtCmdHandlingStart(); + iDecodeInfo.iFirstDecode = ETrue; + iDecodeInfo.iDecodeIndex = 0; + HandleNextDecodedCommand(); + FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not supported) complete") )); + aPartialInput = EFalse; + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Manages request to abort command handling +// --------------------------------------------------------------------------- +// +EXPORT_C TInt CDunAtCmdHandler::ManageAbortRequest() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest()") )); + // Just forward the request, do no other own processing + TInt retVal = iCmdPusher->ManageAbortRequest(); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest() complete") )); + return retVal; + } + +// --------------------------------------------------------------------------- +// Sets end of command line marker on for the possible series of AT commands. +// --------------------------------------------------------------------------- +// +EXPORT_C void CDunAtCmdHandler::SetEndOfCmdLine( TBool aClearInput ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine()") )); + ManageEndOfCmdHandling( EFalse, ETrue, aClearInput ); + FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") )); + } + +// --------------------------------------------------------------------------- +// Stops sending of AT command from parse buffer +// --------------------------------------------------------------------------- +// +EXPORT_C TInt CDunAtCmdHandler::Stop() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::Stop()") )); + // Only stop iCmdPusher here, not iUrcHandlers! + if ( iHandleState != EDunStateAtCmdHandling ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() (not ready) complete" ))); + return KErrNotReady; + } + iCmdPusher->Stop(); + iHandleState = EDunStateIdle; + FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") )); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Starts URC message handling +// --------------------------------------------------------------------------- +// +EXPORT_C TInt CDunAtCmdHandler::StartUrc() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc()") )); + TInt i; + TInt count = iUrcHandlers.Count(); + for ( i=0; iIssueRequest(); + if ( retTemp!=KErrNone && retTemp!=KErrNotReady ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc() (ERROR) complete") )); + return retTemp; + } + } + FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc() complete") )); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Stops URC message handling +// --------------------------------------------------------------------------- +// +EXPORT_C TInt CDunAtCmdHandler::StopUrc() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::StopUrc()") )); + TInt i; + TInt retVal = KErrNone; + TInt count = iUrcHandlers.Count(); + for ( i=0; iStop(); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::StopUrc() complete") )); + return retVal; + } + +// --------------------------------------------------------------------------- +// CDunAtCmdHandler::CDunAtCmdHandler +// --------------------------------------------------------------------------- +// +CDunAtCmdHandler::CDunAtCmdHandler( MDunAtCmdStatusReporter* aUpstream, + MDunStreamManipulator* aDownstream, + const TDesC8* aConnectionName ) : + iUpstream( aUpstream ), + iDownstream( aDownstream ), + iConnectionName( aConnectionName ) + { + Initialize(); + } + +// --------------------------------------------------------------------------- +// CDunAtCmdHandler::ConstructL +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::ConstructL() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL()") )); + if ( !iUpstream || !iDownstream || !iConnectionName ) + { + User::Leave( KErrGeneral ); + } + // Connect to AT command extension (must succeed) + TInt retTemp = KErrNone; + CleanupClosePushL( iAtCmdExt ); + retTemp = iAtCmdExt.Connect( EDunATExtension, *iConnectionName ); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() connect (%d)"), retTemp)); + User::Leave( retTemp ); + } + CleanupClosePushL( iAtCmdExtCommon ); + retTemp = iAtCmdExtCommon.Connect( *iConnectionName ); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() common connect (%d)"), retTemp)); + User::Leave( retTemp ); + } + // Create the array of special commands + CreateSpecialCommandsL(); + // Create the plugin handlers + CreatePluginHandlersL(); + // Create the listeners + CDunAtEcomListen* ecomListen = CDunAtEcomListen::NewLC( &iAtCmdExt, this ); + CDunAtModeListen* modeListen = CDunAtModeListen::NewLC( &iAtCmdExtCommon, + this ); + CDunAtNvramListen* nvramListen = CDunAtNvramListen::NewLC( &iAtCmdExt, + &iAtCmdExtCommon ); + // Set the default modes (+report) and characters + GetAndSetDefaultSettingsL(); + // Start listening + ecomListen->IssueRequest(); + modeListen->IssueRequest(); + nvramListen->IssueRequest(); + CleanupStack::Pop( nvramListen ); + CleanupStack::Pop( modeListen ); + CleanupStack::Pop( ecomListen ); + CleanupStack::Pop( &iAtCmdExtCommon ); + CleanupStack::Pop( &iAtCmdExt ); + iEcomListen = ecomListen; + iModeListen = modeListen; + iNvramListen = nvramListen; + FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() complete") )); + } + +// --------------------------------------------------------------------------- +// Initializes this class +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::Initialize() + { + // Don't initialize iUpstream here (it is set through NewL) + // Don't initialize iDownstream here (it is set through NewL) + // Don't initialize iConnectionName here (it is set through NewL) + iHandleState = EDunStateIdle; + iCarriageReturn = 0; + iLineFeed = 0; + iBackspace = 0; + iCommand = NULL; + iDecodeInfo.iFirstDecode = ETrue; + iDecodeInfo.iDecodeIndex = KErrNotFound; + iDecodeInfo.iPrevChar = 0; + iDecodeInfo.iPrevExists = EFalse; + iCmdPusher = NULL; + iEcomListen = NULL; + iModeListen = NULL; + iNvramListen = NULL; + iDataMode = EFalse; + iEchoOn = EFalse; + iQuietOn = EFalse; + iVerboseOn = EFalse; + iEndIndex = KErrNotFound; + } + +// --------------------------------------------------------------------------- +// Creates plugin handlers for this class +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::CreatePluginHandlersL() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL()") )); + if ( !iAtCmdExt.Handle() ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL() complete") )); + User::Leave( KErrGeneral ); + } + // First create the command reply pusher + CDunAtCmdPusher* cmdPusher = CDunAtCmdPusher::NewLC( &iAtCmdExt, + this, + iDownstream, + &iOkBuffer ); + // Next create the URC handlers + TInt i; + TInt numOfPlugins = iAtCmdExt.NumberOfPlugins(); + for ( i=0; iDes(); + specialCmdPtr.Copy( iInputBuffer ); + specialCmdPtr.UpperCase(); + iSpecials.AppendL( specialCmd ); + CleanupStack::Pop( specialCmd ); + } + iInputBuffer.Zero(); + FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL() complete") )); + } + +// --------------------------------------------------------------------------- +// Recreates special command data. +// This is done when a plugin is installed or uninstalled. +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::RecreateSpecialCommands() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RecreateSpecialCommands()") )); + iSpecials.ResetAndDestroy(); + TRAPD( retTrap, CreateSpecialCommandsL() ); + FTRACE(FPrint( _L("CDunAtCmdHandler::RecreateSpecialCommands() complete") )); + return retTrap; + } + +// --------------------------------------------------------------------------- +// Gets default settings from RATExtCommon and sets them to RATExt +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::GetAndSetDefaultSettingsL() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL()") )); + // Note: Let's assume command mode is off by default + TUint modeSet = GetCurrentModeL( KModeEcho | KModeQuiet | KModeVerbose ); + iEchoOn = ( modeSet & KEchoModeBase ) ? ETrue : EFalse; + iQuietOn = ( modeSet & KQuietModeBase ) ? ETrue : EFalse; + iVerboseOn = ( modeSet & KVerboseModeBase ) ? ETrue : EFalse; + iCarriageReturn = GetCurrentModeL( KModeCarriage ); + iLineFeed = GetCurrentModeL( KModeLineFeed ); + iBackspace = GetCurrentModeL( KModeBackspace ); + iAtCmdExt.ReportQuietModeChange( iQuietOn ); + iAtCmdExt.ReportVerboseModeChange( iVerboseOn ); + iAtCmdExt.ReportCharacterChange( ECharTypeCarriage, iCarriageReturn ); + iAtCmdExt.ReportCharacterChange( ECharTypeLineFeed, iLineFeed ); + iAtCmdExt.ReportCharacterChange( ECharTypeBackspace, iBackspace ); + RegenerateReplyStrings(); + FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn )); + FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() settings: CR=%u, LF=%u, BS=%u"), iCarriageReturn, iLineFeed, iBackspace )); + FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() complete") )); + } + +// --------------------------------------------------------------------------- +// Regenerates the reply strings based on settings +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::RegenerateReplyStrings() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateReplyStrings()") )); + TBool retVal = EFalse; + retVal |= RegenerateOkReply(); + retVal |= RegenerateErrorReply(); + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateReplyStrings() complete") )); + return retVal; + } + +// --------------------------------------------------------------------------- +// Regenerates the ok reply based on settings +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::RegenerateOkReply() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply()") )); + iOkBuffer.Zero(); + if ( iQuietOn ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() (quiet) complete") )); + return ETrue; + } + if ( iVerboseOn ) + { + _LIT8( KVerboseError, "OK" ); + iOkBuffer.Append( iCarriageReturn ); + iOkBuffer.Append( iLineFeed ); + iOkBuffer.Append( KVerboseError ); + iOkBuffer.Append( iCarriageReturn ); + iOkBuffer.Append( iLineFeed ); + } + else + { + _LIT8( KNumericError, "4" ); + iOkBuffer.Append( KNumericError ); + iOkBuffer.Append( iCarriageReturn ); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Regenerates the error reply based on settings +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::RegenerateErrorReply() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply()") )); + iErrorBuffer.Zero(); + if ( iQuietOn ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() (quiet) complete") )); + return ETrue; + } + if ( iVerboseOn ) + { + _LIT8( KVerboseError, "ERROR" ); + iErrorBuffer.Append( iCarriageReturn ); + iErrorBuffer.Append( iLineFeed ); + iErrorBuffer.Append( KVerboseError ); + iErrorBuffer.Append( iCarriageReturn ); + iErrorBuffer.Append( iLineFeed ); + } + else + { + _LIT8( KNumericError, "4" ); + iErrorBuffer.Append( KNumericError ); + iErrorBuffer.Append( iCarriageReturn ); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Gets current mode +// --------------------------------------------------------------------------- +// +TUint CDunAtCmdHandler::GetCurrentModeL( TUint aMask ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL()") )); + TUint maskCheck = aMask & ( ~KSupportedModes ); + if ( maskCheck != 0 ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() (not supported) complete") )); + User::Leave( KErrNotSupported ); + } + TUint newMode = 0; + TInt retTemp = iAtCmdExtCommon.GetMode( aMask, newMode ); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() (ERROR) complete") )); + User::Leave( retTemp ); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() complete") )); + return newMode & (KModeChanged-1); + } + +// --------------------------------------------------------------------------- +// Instantiates one URC message handling class instance and adds it to the URC +// message handler array +// --------------------------------------------------------------------------- +// +CDunAtUrcHandler* CDunAtCmdHandler::AddOneUrcHandlerL() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::AddOneUrcHandlerL()") )); + CDunAtUrcHandler* urcHandler = CDunAtUrcHandler::NewLC( &iAtCmdExt, + iDownstream ); + iUrcHandlers.AppendL( urcHandler ); + CleanupStack::Pop( urcHandler ); + FTRACE(FPrint( _L("CDunAtCmdHandler::AddOneUrcHandlerL() complete") )); + return urcHandler; + } + +// --------------------------------------------------------------------------- +// Deletes all instantiated URC message handlers +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::DeletePluginHandlers() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::DeletePluginHandlers()") )); + delete iCmdPusher; + iCmdPusher = NULL; + TInt i; + TInt count = iUrcHandlers.Count(); + for ( i=0; i KDunChSetMaxCharLen ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (wrong length) complete") )); + return EFalse; + } + if ( iEchoOn ) + { + iEchoBuffer.Copy( aDes ); + iDownstream->NotifyDataPushRequest( &iEchoBuffer, NULL ); + FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() complete") )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (not started) complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Handles backspace and cancel characters +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::HandleSpecialCharacters( TDesC8& aCommand ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters()") )); + if ( aCommand.Length() != KDunChSetMaxCharLen ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (wrong length) complete") )); + return EFalse; + } + if ( aCommand[0] == iBackspace ) + { + TInt bufferLength = iInputBuffer.Length(); + if ( bufferLength > 0 ) + { + iInputBuffer.SetLength( bufferLength-1 ); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (backspace) complete") )); + return ETrue; + } + if ( aCommand[0] == KDunCancel ) + { + ResetParseBuffers(); // More processing here? + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (cancel) complete") )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Appends command to parse buffer +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::AppendCommandToInputBuffer( TDesC8& aCommand, + TBool& aEndFound ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer()") )); + aEndFound = EFalse; + TInt cmdBufIndex = 0; + TInt cmdBufLim = aCommand.Length(); + while ( cmdBufIndex < cmdBufLim ) + { + if ( iInputBuffer.Length() == iInputBuffer.MaxLength() ) + { + // 1) If output is full and end found from input + // -> reset buffers and overflow found + // 2) If output is full and end not found from input + // -> don't reset buffers and overflow found + TInt foundIndex = FindEndOfCommand( aCommand ); + if ( foundIndex >= 0 ) + { + aEndFound = ETrue; + ResetParseBuffers(); + FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (reset) complete") )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (overflow) complete") )); + return ETrue; + } + TChar character = aCommand[cmdBufIndex]; + if ( IsEndOfCommand(character) ) + { + aEndFound = ETrue; + iEndIndex = cmdBufIndex; + break; + } + iInputBuffer.Append( aCommand[cmdBufIndex] ); + cmdBufIndex++; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Handles next decoded command from input buffer +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::HandleNextDecodedCommand() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand()") )); + if ( iHandleState != EDunStateAtCmdHandling ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (not ready) complete") )); + return ETrue; + } + TBool extracted = ExtractNextDecodedCommand(); + if ( !extracted ) + { + ManageEndOfCmdHandling( ETrue, ETrue, ETrue ); + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (last) complete") )); + return ETrue; + } + // Next convert the decoded AT command to uppercase + // Don't check for case status -> let mixed cases pass + iParseInfo.iSendBuffer.Copy( iDecodeInfo.iDecodeBuffer ); + TInt maxLength = iParseInfo.iSendBuffer.MaxLength(); + TPtr8 upperDes( &iParseInfo.iSendBuffer[0], iParseInfo.iLimit, maxLength ); + upperDes.UpperCase(); + // Next always send the command to ATEXT + iCmdPusher->IssueRequest( iParseInfo.iSendBuffer ); + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Manages end of AT command handling +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal, + TBool aNotifyLocal, + TBool aClearInput ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") )); + if ( iInputBuffer.Length() > 0 ) + { + iLastBuffer.Copy( iInputBuffer ); + } + ResetParseBuffers( aClearInput ); + iHandleState = EDunStateIdle; + if ( aNotifyLocal ) + { + iCmdPusher->SetEndOfCmdLine(); + } + if ( !aNotifyExternal ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") )); + return; + } + // Note: here we need to avoid internal recursion when parsing the + // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the + // same upstream block. + // Skip all the extra markers except the one we already know to exist. + TInt i; + TInt startVal = iEndIndex + 1; + TInt foundIndex = KErrNotFound; + TInt count = iCommand->Length(); + for ( i=startVal; iNotifyAtCmdHandlingEnd( foundIndex ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") )); + } + +// --------------------------------------------------------------------------- +// Extracts next decoded command from input buffer to decode buffer +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::ExtractNextDecodedCommand( TBool aPeek ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") )); + iParseInfo.iLimit = KErrNotFound; + TDunDecodeInfo oldInfo = iDecodeInfo; + iDecodeInfo.iDecodeBuffer.Zero(); + // Find start of decode command from input buffer + TBool extendedCmd = EFalse; + TInt startIndex = iDecodeInfo.iDecodeIndex; + startIndex = FindStartOfDecodedCommand( iInputBuffer, + startIndex, + extendedCmd ); + if ( startIndex < 0 ) + { + RestoreOldDecodeInfo( aPeek, oldInfo ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") )); + return EFalse; + } + // Find end of decode command from input buffer + TBool extendedEnd = EFalse; + TBool oneCharCmd = EFalse; + TBool specialCmd = EFalse; + TInt endIndex = KErrNotFound; + if ( extendedCmd ) + { + extendedEnd = CheckExtendedCommand( startIndex, endIndex ); + } + else + { + specialCmd = CheckSpecialCommand( startIndex, endIndex ); + if ( !specialCmd ) + { + CheckBasicCommand( startIndex, endIndex, oneCharCmd ); + } + } + if ( endIndex < startIndex ) + { + RestoreOldDecodeInfo( aPeek, oldInfo ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") )); + return EFalse; + } + TInt cmdLength = endIndex - startIndex + 1; + // If the limit was not already set then do it now + if ( iParseInfo.iLimit < 0 ) + { + iParseInfo.iLimit = cmdLength; + } + // Next create a new command + if ( !iDecodeInfo.iFirstDecode && !oneCharCmd && !specialCmd ) + { + _LIT( KAtMsg, "AT" ); + iDecodeInfo.iDecodeBuffer.Append( KAtMsg ); + iParseInfo.iLimit += 2; // Length of "AT" + // Note: The length of iDecodeBuffer is not exceeded here because "AT" + // is added only for the second commands after that. + } + TPtrC8 decodedCmd = iInputBuffer.Mid( startIndex, cmdLength ); + iDecodeInfo.iDecodeBuffer.Append( decodedCmd ); + // Set index for next round + iDecodeInfo.iFirstDecode = EFalse; + iDecodeInfo.iDecodeIndex = endIndex + 1; + if ( extendedEnd ) // skip the extra ';' + { + iDecodeInfo.iDecodeIndex++; + } + RestoreOldDecodeInfo( aPeek, oldInfo ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() complete") )); + return ETrue; + } + +// --------------------------------------------------------------------------- +// Restores old decode info. For ExtractNextDecodedCommand() when aPeeks is +// ETrue. +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::RestoreOldDecodeInfo( TBool aPeek, + TDunDecodeInfo& aOldInfo ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo()") )); + if ( aPeek ) + { + iDecodeInfo = aOldInfo; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") )); + } + +// --------------------------------------------------------------------------- +// Finds end of an AT command +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::FindEndOfCommand( TDesC8& aDes, TInt aStartIndex ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand()") )); + TInt i; + TInt length = aDes.Length(); + for ( i=aStartIndex; i=iInputBuffer.Length() ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand() (index out of bounds) complete") )); + return EFalse; + } + TChar character = iInputBuffer[aIndex]; + if ( character==',' || character==';' || character=='@' || character=='!' || + IsOneCharacterACommand(aIndex) ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand() complete") )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand() (not found) complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Check if one character "A" command +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::IsOneCharacterACommand( TInt aIndex ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand()") )); + if ( aIndex<0 || aIndex>=iInputBuffer.Length() ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (index out of bounds) complete") )); + return EFalse; + } + if ( iInputBuffer[aIndex]!='a' && iInputBuffer[aIndex]!='A' ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (not found) complete") )); + return EFalse; + } + TBool prevAlpha = EFalse; + TBool nextAlpha = EFalse; + TBool nextSlash = EFalse; + TInt length = iInputBuffer.Length(); + if ( iDecodeInfo.iPrevExists && iDecodeInfo.iPrevChar.IsAlpha() ) + { + prevAlpha = ETrue; + } + if ( aIndex+1 < length ) + { + TChar nextChar = iInputBuffer[aIndex+1]; + if ( nextChar.IsAlpha() ) + { + nextAlpha = ETrue; + } + if ( nextChar == '/' ) + { + nextSlash = ETrue; + } + } + if ( prevAlpha || nextAlpha || nextSlash ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (not found) complete") )); + return EFalse; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (complete) complete") )); + return ETrue; + } + +// --------------------------------------------------------------------------- +// Check if "A/" command +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::IsASlashCommand() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand()") )); + if ( iInputBuffer.Length() == 2 ) + { + if ( iInputBuffer[1] == '/' && + (iInputBuffer[0] == 'A' || iInputBuffer[0] == 'a') ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (found) complete") )); + return ETrue; + } + } + FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (not found) complete") )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Handles "A/" command +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::HandleASlashCommand() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand()") )); + // If not "A/" command, return + if ( !IsASlashCommand() ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (no push) complete") )); + return EFalse; + } + // If "A/" command and last buffer exist, set the last buffer as the current buffer + if ( iLastBuffer.Length() > 0 ) + { + iInputBuffer.Copy( iLastBuffer ); + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (copy) complete") )); + return EFalse; + } + // Last buffer not set so return "ERROR" if quiet mode not on + if ( iQuietOn ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (quiet) complete") )); + return EFalse; + } + iDownstream->NotifyDataPushRequest( &iErrorBuffer, NULL ); + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() complete") )); + return ETrue; + } + +// --------------------------------------------------------------------------- +// Resets parse buffers +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::ResetParseBuffers( TBool aClearInput ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers()") )); + if ( aClearInput ) + { + iInputBuffer.Zero(); + } + iDecodeInfo.iFirstDecode = ETrue; + iDecodeInfo.iDecodeIndex = 0; + iDecodeInfo.iPrevExists = EFalse; + iDecodeInfo.iDecodeBuffer.Zero(); + FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers() complete") )); + } + +// --------------------------------------------------------------------------- +// Manages command mode change +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::ManageCommandModeChange( TUint aMode ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange()" ) )); + if ( aMode & KCommandModeChanged ) + { + if ( aMode & KModeCommand ) // command mode ON + { + ReportCommandModeChange( ETrue ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() command mode changed ON" ) )); + } + else // command mode OFF + { + ReportCommandModeChange( EFalse ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() command mode changed OFF" ) )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() (change) complete" ) )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange()" ) )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Reports command mode start/end change +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::ReportCommandModeChange( TBool aStart ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ReportCommandModeChange()" ) )); + TInt i; + TInt count = iCmdCallbacks.Count(); + if ( aStart ) + { + if ( iDataMode ) + { + for ( i=0; iNotifyCommandModeStart(); + } + iDataMode = EFalse; + } + } + else // end + { + if ( !iDataMode ) + { + for ( i=0; iNotifyCommandModeEnd(); + } + iDataMode = ETrue; + } + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ReportCommandModeChange() complete" ) )); + } + +// --------------------------------------------------------------------------- +// Manages echo mode change +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::ManageEchoModeChange( TUint aMode ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange()" ) )); + if ( aMode & KEchoModeChanged ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() checking echo mode..." ) )); + if ( aMode & KModeEcho ) // echo mode ON + { + iEchoOn = ETrue; + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() echo mode changed ON" ) )); + } + else // echo mode OFF + { + iEchoOn = EFalse; + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() echo mode changed OFF" ) )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() (change) complete" ) )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() complete" ) )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Manages quiet mode change +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::ManageQuietModeChange( TUint aMode ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange()" ) )); + if ( aMode & KQuietModeChanged ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() checking quiet mode..." ) )); + if ( aMode & KModeQuiet ) // quiet mode ON + { + iAtCmdExt.ReportQuietModeChange( ETrue ); + iQuietOn = ETrue; + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() quiet mode changed ON" ) )); + } + else // quiet mode OFF + { + iAtCmdExt.ReportQuietModeChange( EFalse ); + iQuietOn = EFalse; + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() quiet mode changed OFF" ) )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() (change) complete" ) )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() complete" ) )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Manages quiet mode change +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::ManageVerboseModeChange( TUint aMode ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange()" ) )); + if ( aMode & KVerboseModeChanged ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() checking verbose mode..." ) )); + if ( aMode & KModeVerbose ) // verbose mode ON + { + iAtCmdExt.ReportVerboseModeChange( ETrue ); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyVerboseStatusChange() verbose mode changed ON" ) )); + } + else // verbose mode OFF + { + iAtCmdExt.ReportVerboseModeChange( EFalse ); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyVerboseStatusChange() verbose mode changed OFF" ) )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() (change) complete" ) )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() complete" ) )); + return EFalse; + } + +// --------------------------------------------------------------------------- +// Manages character change +// --------------------------------------------------------------------------- +// +void CDunAtCmdHandler::ManageCharacterChange( TUint aMode ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange()" ) )); + if ( aMode & KCarriageChanged ) + { + iCarriageReturn = aMode & (KModeChanged-1); + iAtCmdExt.ReportCharacterChange( ECharTypeCarriage, iCarriageReturn ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() carriage return changed" ) )); + } + else if ( aMode & KLineFeedChanged ) + { + iLineFeed = aMode & (KModeChanged-1); + iAtCmdExt.ReportCharacterChange( ECharTypeLineFeed, iLineFeed ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() line feed changed" ) )); + } + else if ( aMode & KBackspaceChanged ) + { + iBackspace = aMode & (KModeChanged-1); + iAtCmdExt.ReportCharacterChange( ECharTypeBackspace, iBackspace ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() backspace changed" ) )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() complete" ) )); + } + +// --------------------------------------------------------------------------- +// From class MDunAtCmdPusher. +// Notifies about end of AT command processing. This is after all reply data +// for an AT command is multiplexed to the downstream. +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::NotifyEndOfProcessing( TInt /*aError*/ ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing()" ) )); + HandleNextDecodedCommand(); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) )); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From class MDunAtCmdPusher. +// Notifies about request to stop AT command handling for the rest of the +// command line data +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()" ) )); + TInt retVal = Stop(); + ManageEndOfCmdHandling( ETrue, EFalse, ETrue ); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() complete" ) )); + return retVal; + } + +// --------------------------------------------------------------------------- +// From class MDunAtCmdPusher. +// Notifies about request to peek for the next command +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::NotifyNextCommandPeekRequest() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") )); + TBool extracted = ExtractNextDecodedCommand( ETrue ); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") )); + return extracted; + } + +// --------------------------------------------------------------------------- +// From class MDunAtEcomListen. +// Notifies about new plugin installation +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::NotifyPluginInstallation( TUid& /*aPluginUid*/ ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation()" ) )); + CDunAtUrcHandler* urcHandler = NULL; + TRAPD( retTrap, urcHandler=AddOneUrcHandlerL() ); + if ( retTrap != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (trapped!) complete" ) )); + return retTrap; + } + TInt retTemp = urcHandler->IssueRequest(); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (issuerequest) complete" ) )); + return retTemp; + } + TUid ownerUid = urcHandler->OwnerUid(); + iAtCmdExt.ReportListenerUpdateReady( ownerUid, EEcomTypeInstall ); + // As a last step recreate the special command data + retTemp = RecreateSpecialCommands(); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (recreate) complete" ) )); + return retTemp; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() complete" ) )); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From class MDunAtEcomListen. +// Notifies about existing plugin uninstallation +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::NotifyPluginUninstallation( TUid& aPluginUid ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation()" ) )); + TInt i; + TInt count = iUrcHandlers.Count(); + for ( i=count-1; i>=0; i-- ) + { + TUid ownerUid = iUrcHandlers[i]->OwnerUid(); + if ( ownerUid == aPluginUid ) + { + delete iUrcHandlers[i]; + iUrcHandlers.Remove( i ); + iAtCmdExt.ReportListenerUpdateReady( ownerUid, + EEcomTypeUninstall ); + } + } + // As a last step recreate the special command data + TInt retTemp = RecreateSpecialCommands(); + if ( retTemp != KErrNone ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation() (recreate) complete" ) )); + return retTemp; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation() complete" ) )); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From class MDunAtModeListen. +// Gets called on mode status change +// --------------------------------------------------------------------------- +// +TInt CDunAtCmdHandler::NotifyModeStatusChange( TUint aMode ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange()") )); + TBool commandModeSet = ManageCommandModeChange( aMode ); + TBool echoModeSet = ManageEchoModeChange( aMode ); + TBool quietModeSet = ManageQuietModeChange( aMode ); + TBool verboseModeSet = ManageVerboseModeChange( aMode ); + if ( quietModeSet || verboseModeSet ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn )); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() (regenerate) mode set" ) )); + RegenerateReplyStrings(); + return KErrNone; + } + // Keep the following after "quietModeSet || verboseModeSet" in order to + // regenerate the reply also if two modes change at the same time + if ( commandModeSet || echoModeSet ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn )); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() mode set" ) )); + return KErrNone; + } + ManageCharacterChange( aMode ); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: CR=%u, LF=%u, BS=%u"), iCarriageReturn, iLineFeed, iBackspace )); + RegenerateReplyStrings(); + FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() complete") )); + return KErrNone; + }