localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp
changeset 24 c55c8fddf124
parent 21 23264c07fd05
equal deleted inserted replaced
21:23264c07fd05 24:c55c8fddf124
     1 /*
       
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  AT command handler and notifier
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19  * Points to consider:
       
    20  * - Each of the AT commands sent to ATEXT are converted to upper case form.
       
    21  *   Thus the ATEXT plugins don't need to check for case. The conversion to
       
    22  *   upper case form stops when carriage return or '=' character is found.
       
    23  */
       
    24 
       
    25 /*
       
    26  * The AT command handling is splitted to two parts on high level:
       
    27  * 1) Splitter: splitting the sub-commands in a command line to multiple ones
       
    28  *    for ATEXT to process.
       
    29  * 2) Combiner: combining the replies coming from ATEXT using a filter
       
    30  *    (the filter categories are explained in DunAtCmdPusher.cpp)
       
    31  */
       
    32 
       
    33 #include "DunAtCmdHandler.h"
       
    34 #include "DunAtUrcHandler.h"
       
    35 #include "DunDownstream.h"
       
    36 #include "DunDebug.h"
       
    37 
       
    38 const TInt8 KDunCancel = 24;  // Used for line editing, cancel character
       
    39 const TInt8 KDunEscape = 27;  // Used for editor ending, escape character
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 // Two-phased constructor.
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 EXPORT_C CDunAtCmdHandler* CDunAtCmdHandler::NewL(
       
    46     MDunAtCmdStatusReporter* aUpstream,
       
    47     MDunStreamManipulator* aDownstream,
       
    48     const TDesC8* aConnectionName )
       
    49     {
       
    50     CDunAtCmdHandler* self = new (ELeave) CDunAtCmdHandler(
       
    51         aUpstream,
       
    52         aDownstream,
       
    53         aConnectionName );
       
    54     CleanupStack::PushL( self );
       
    55     self->ConstructL();
       
    56     CleanupStack::Pop( self );
       
    57     return self;
       
    58     }
       
    59 
       
    60 // ---------------------------------------------------------------------------
       
    61 // Destructor.
       
    62 // ---------------------------------------------------------------------------
       
    63 //
       
    64 CDunAtCmdHandler::~CDunAtCmdHandler()
       
    65     {
       
    66     FTRACE(FPrint( _L("CDunAtCmdHandler::~CDunAtCmdHandler()") ));
       
    67     ResetData();
       
    68     FTRACE(FPrint( _L("CDunAtCmdHandler::~CDunAtCmdHandler() complete") ));
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // Resets data to initial values
       
    73 // ---------------------------------------------------------------------------
       
    74 //
       
    75 EXPORT_C void CDunAtCmdHandler::ResetData()
       
    76     {
       
    77     FTRACE(FPrint( _L("CDunAtCmdHandler::ResetData()") ));
       
    78     // APIs affecting this:
       
    79     // IssueRequest()
       
    80     Stop();
       
    81     // NewL()
       
    82     DeletePluginHandlers();
       
    83     delete iCmdEchoer;
       
    84     iCmdEchoer = NULL;
       
    85     delete iNvramListen;
       
    86     iNvramListen = NULL;
       
    87     delete iModeListen;
       
    88     iModeListen = NULL;
       
    89     delete iEcomListen;
       
    90     iEcomListen = NULL;
       
    91     delete iAtSpecialCmdHandler;
       
    92     iAtSpecialCmdHandler = NULL;
       
    93     if ( iAtCmdExtCommon.Handle() )
       
    94         {
       
    95         iAtCmdExtCommon.SynchronousClose();
       
    96         iAtCmdExtCommon.Close();
       
    97         }
       
    98     if ( iAtCmdExt.Handle() )
       
    99         {
       
   100         iAtCmdExt.SynchronousClose();
       
   101         iAtCmdExt.Close();
       
   102         }
       
   103     iSpecials.ResetAndDestroy();
       
   104     iSpecials.Close();
       
   105     // AddCmdModeCallback()
       
   106     iCmdCallbacks.Close();
       
   107     // Internal
       
   108     Initialize();
       
   109     FTRACE(FPrint( _L("CDunAtCmdHandler::ResetData() complete") ));
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------------------------
       
   113 // Adds callback for command mode notification
       
   114 // The callback will be called when command mode starts or ends
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 EXPORT_C TInt CDunAtCmdHandler::AddCmdModeCallback( MDunCmdModeMonitor* aCallback )
       
   118     {
       
   119     FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback()" ) ));
       
   120     if ( !aCallback )
       
   121         {
       
   122         FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (aCallback) not initialized!" ) ));
       
   123         return KErrGeneral;
       
   124         }
       
   125     TInt retTemp = iCmdCallbacks.Find( aCallback );
       
   126     if ( retTemp != KErrNotFound )
       
   127         {
       
   128         FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (already exists) complete" ) ));
       
   129         return KErrAlreadyExists;
       
   130         }
       
   131     retTemp = iCmdCallbacks.Append( aCallback );
       
   132     if ( retTemp != KErrNone )
       
   133         {
       
   134         FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (append failed!) complete" ) ));
       
   135         return retTemp;
       
   136         }
       
   137     FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() complete" ) ));
       
   138     return KErrNone;
       
   139     }
       
   140 
       
   141 // ---------------------------------------------------------------------------
       
   142 // Parses an AT command
       
   143 // ---------------------------------------------------------------------------
       
   144 //
       
   145 EXPORT_C TInt CDunAtCmdHandler::ParseCommand( TDesC8& aCommand,
       
   146                                               TBool& aPartialInput )
       
   147     {
       
   148     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") ));
       
   149     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") ));
       
   150     FTRACE(FPrintRaw(aCommand) );
       
   151     TBool editorMode = iCmdPusher->EditorMode();
       
   152     if ( editorMode )
       
   153         {
       
   154         // Note: return here with "no partial input" and some error to fool
       
   155         // CDunUpstream into not reissuing the read request.
       
   156         iCmdPusher->IssueRequest( aCommand, EFalse );
       
   157         aPartialInput = EFalse;
       
   158         return KErrGeneral;
       
   159         }
       
   160     iCommand = &aCommand;  // iCommand only for normal mode
       
   161     // Manage partial AT command
       
   162     TBool needsCarriage = ETrue;
       
   163     TBool okToExit = ManagePartialCommand( aCommand, needsCarriage );
       
   164     if ( okToExit )
       
   165         {
       
   166         FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (ok to exit) complete") ));
       
   167         aPartialInput = ETrue;
       
   168         return KErrNone;
       
   169         }
       
   170     if ( iHandleState != EDunStateIdle )
       
   171         {
       
   172         aPartialInput = EFalse;
       
   173         ResetParseBuffers();
       
   174         FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not ready) complete") ));
       
   175         return KErrNotReady;
       
   176         }
       
   177     TBool pushStarted = HandleASlashCommand();
       
   178     if ( pushStarted )
       
   179         {
       
   180         // Note: return here with "partial input" status to fool CDunUpstream
       
   181         // into reissuing the read request. The AT command has not really
       
   182         // started yet so this is necessary.
       
   183         aPartialInput = ETrue;
       
   184         ResetParseBuffers();
       
   185         FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (A/) complete") ));
       
   186         return KErrNone;
       
   187         }
       
   188     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received total:") ));
       
   189     FTRACE(FPrintRaw(iInputBuffer) );
       
   190     iHandleState = EDunStateAtCmdHandling;
       
   191     iUpstream->NotifyAtCmdHandlingStart();
       
   192     iDecodeInfo.iFirstDecode = ETrue;
       
   193     iDecodeInfo.iDecodeIndex = 0;
       
   194     HandleNextDecodedCommand();
       
   195     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() complete") ));
       
   196     aPartialInput = EFalse;
       
   197     return KErrNone;
       
   198     }
       
   199 
       
   200 // ---------------------------------------------------------------------------
       
   201 // Manages request to abort command handling
       
   202 // ---------------------------------------------------------------------------
       
   203 //
       
   204 EXPORT_C TInt CDunAtCmdHandler::ManageAbortRequest()
       
   205     {
       
   206     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest()") ));
       
   207     // Just forward the request, do no other own processing
       
   208     TInt retVal = iCmdPusher->ManageAbortRequest();
       
   209     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest() complete") ));
       
   210     return retVal;
       
   211     }
       
   212 
       
   213 // ---------------------------------------------------------------------------
       
   214 // Sets end of command line marker on for the possible series of AT commands.
       
   215 // ---------------------------------------------------------------------------
       
   216 //
       
   217 EXPORT_C void CDunAtCmdHandler::SetEndOfCmdLine( TBool aClearInput )
       
   218     {
       
   219     FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine()") ));
       
   220     ManageEndOfCmdHandling( EFalse, ETrue, aClearInput );
       
   221     FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") ));
       
   222     }
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 // Sends a character to be echoed
       
   226 // ---------------------------------------------------------------------------
       
   227 //
       
   228 EXPORT_C TInt CDunAtCmdHandler::SendEchoCharacter( const TDesC8* aInput,
       
   229                                                    MDunAtCmdEchoer* aCallback )
       
   230     {
       
   231     FTRACE(FPrint( _L("CDunAtCmdHandler::SendEchoCharacter()") ));
       
   232     TInt retVal = iCmdEchoer->SendEchoCharacter( aInput, aCallback );
       
   233     FTRACE(FPrint( _L("CDunAtCmdHandler::SendEchoCharacter() complete") ));
       
   234     return retVal;
       
   235     }
       
   236 
       
   237 // ---------------------------------------------------------------------------
       
   238 // Stops sending of AT command from parse buffer
       
   239 // ---------------------------------------------------------------------------
       
   240 //
       
   241 EXPORT_C TInt CDunAtCmdHandler::Stop()
       
   242     {
       
   243     FTRACE(FPrint( _L("CDunAtCmdHandler::Stop()") ));
       
   244     // Only stop iCmdPusher here, not iUrcHandlers!
       
   245     if ( iHandleState != EDunStateAtCmdHandling )
       
   246         {
       
   247         FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() (not ready) complete" )));
       
   248         return KErrNotReady;
       
   249         }
       
   250     iCmdPusher->Stop();
       
   251     // The line below is used in the case when this function is called by
       
   252     // CDunUpstream as a result of "data mode ON" change notification.
       
   253     // In this case it is possible that HandleNextDecodedCommand() returns
       
   254     // without resetting the iInputBuffer because of the way it checks the
       
   255     // iHandleState.
       
   256     ManageEndOfCmdHandling( EFalse, ETrue, ETrue );
       
   257     FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") ));
       
   258     return KErrNone;
       
   259     }
       
   260 
       
   261 // ---------------------------------------------------------------------------
       
   262 // Starts URC message handling
       
   263 // ---------------------------------------------------------------------------
       
   264 //
       
   265 EXPORT_C TInt CDunAtCmdHandler::StartUrc()
       
   266     {
       
   267     FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc()") ));
       
   268     TInt i;
       
   269     TInt count = iUrcHandlers.Count();
       
   270     for ( i=0; i<count; i++ )
       
   271         {
       
   272         TInt retTemp = iUrcHandlers[i]->IssueRequest();
       
   273         if ( retTemp!=KErrNone && retTemp!=KErrNotReady )
       
   274             {
       
   275             FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc() (ERROR) complete") ));
       
   276             return retTemp;
       
   277             }
       
   278         }
       
   279     FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc() complete") ));
       
   280     return KErrNone;
       
   281     }
       
   282 
       
   283 // ---------------------------------------------------------------------------
       
   284 // Stops URC message handling
       
   285 // ---------------------------------------------------------------------------
       
   286 //
       
   287 EXPORT_C TInt CDunAtCmdHandler::StopUrc()
       
   288     {
       
   289     FTRACE(FPrint( _L("CDunAtCmdHandler::StopUrc()") ));
       
   290     TInt i;
       
   291     TInt retVal = KErrNone;
       
   292     TInt count = iUrcHandlers.Count();
       
   293     for ( i=0; i<count; i++ )
       
   294         {
       
   295         retVal = iUrcHandlers[i]->Stop();
       
   296         }
       
   297     FTRACE(FPrint( _L("CDunAtCmdHandler::StopUrc() complete") ));
       
   298     return retVal;
       
   299     }
       
   300 
       
   301 // ---------------------------------------------------------------------------
       
   302 // CDunAtCmdHandler::CDunAtCmdHandler
       
   303 // ---------------------------------------------------------------------------
       
   304 //
       
   305 CDunAtCmdHandler::CDunAtCmdHandler( MDunAtCmdStatusReporter* aUpstream,
       
   306                                     MDunStreamManipulator* aDownstream,
       
   307                                     const TDesC8* aConnectionName ) :
       
   308     iUpstream( aUpstream ),
       
   309     iDownstream( aDownstream ),
       
   310     iConnectionName( aConnectionName )
       
   311     {
       
   312     Initialize();
       
   313     }
       
   314 
       
   315 // ---------------------------------------------------------------------------
       
   316 // CDunAtCmdHandler::ConstructL
       
   317 // ---------------------------------------------------------------------------
       
   318 //
       
   319 void CDunAtCmdHandler::ConstructL()
       
   320     {
       
   321     FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL()") ));
       
   322     if ( !iUpstream || !iDownstream || !iConnectionName )
       
   323         {
       
   324         User::Leave( KErrGeneral );
       
   325         }
       
   326     // Connect to AT command extension (must succeed)
       
   327     TInt retTemp = KErrNone;
       
   328     CleanupClosePushL( iAtCmdExt );
       
   329     retTemp = iAtCmdExt.Connect( EDunATExtension, *iConnectionName );
       
   330     if ( retTemp != KErrNone )
       
   331         {
       
   332         FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() connect (%d)"), retTemp));
       
   333         User::Leave( retTemp );
       
   334         }
       
   335     CleanupClosePushL( iAtCmdExtCommon );
       
   336     retTemp = iAtCmdExtCommon.Connect( *iConnectionName );
       
   337     if ( retTemp != KErrNone )
       
   338         {
       
   339         FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() common connect (%d)"), retTemp));
       
   340         User::Leave( retTemp );
       
   341         }
       
   342     // Create the array of special commands
       
   343     CreateSpecialCommandsL();
       
   344     // Create the plugin handlers
       
   345     CreatePluginHandlersL();
       
   346     // Create the echo handler
       
   347     iCmdEchoer = CDunAtCmdEchoer::NewL( iDownstream );
       
   348     // Create the listeners
       
   349     iEcomListen = CDunAtEcomListen::NewL( &iAtCmdExt, this );
       
   350     iModeListen = CDunAtModeListen::NewL( &iAtCmdExtCommon, this );
       
   351     iNvramListen = CDunAtNvramListen::NewL( &iAtCmdExt, &iAtCmdExtCommon );
       
   352     iAtSpecialCmdHandler = CDunAtSpecialCmdHandler::NewL();
       
   353     // Set the default modes (+report) and characters
       
   354     GetAndSetDefaultSettingsL();
       
   355     // Start listening
       
   356     iEcomListen->IssueRequest();
       
   357     iModeListen->IssueRequest();
       
   358     iNvramListen->IssueRequest();
       
   359     CleanupStack::Pop( &iAtCmdExtCommon );
       
   360     CleanupStack::Pop( &iAtCmdExt );
       
   361     FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() complete") ));
       
   362     }
       
   363 
       
   364 // ---------------------------------------------------------------------------
       
   365 // Initializes this class
       
   366 // ---------------------------------------------------------------------------
       
   367 //
       
   368 void CDunAtCmdHandler::Initialize()
       
   369     {
       
   370     // Don't initialize iUpstream here (it is set through NewL)
       
   371     // Don't initialize iDownstream here (it is set through NewL)
       
   372     // Don't initialize iConnectionName here (it is set through NewL)
       
   373     iHandleState = EDunStateIdle;
       
   374     iCarriageReturn = 0;
       
   375     iLineFeed = 0;
       
   376     iBackspace = 0;
       
   377     iCommand = NULL;
       
   378     iDecodeInfo.iFirstDecode = ETrue;
       
   379     iDecodeInfo.iDecodeIndex = KErrNotFound;
       
   380     iDecodeInfo.iExtendedIndex = KErrNotFound;
       
   381     iDecodeInfo.iPrevChar = 0;
       
   382     iDecodeInfo.iPrevExists = EFalse;
       
   383     iDecodeInfo.iAssignFound = EFalse;
       
   384     iDecodeInfo.iInQuotes = EFalse;
       
   385     iDecodeInfo.iSpecialFound = EFalse;
       
   386     iEditorModeInfo.iContentFound = EFalse;
       
   387     iCmdPusher = NULL;
       
   388     iEcomListen = NULL;
       
   389     iModeListen = NULL;
       
   390     iNvramListen = NULL;
       
   391     iDataMode = EFalse;
       
   392     iEchoOn = EFalse;
       
   393     iQuietOn = EFalse;
       
   394     iVerboseOn = EFalse;
       
   395     iEndIndex = KErrNotFound;
       
   396     }
       
   397 
       
   398 // ---------------------------------------------------------------------------
       
   399 // Creates plugin handlers for this class
       
   400 // ---------------------------------------------------------------------------
       
   401 //
       
   402 void CDunAtCmdHandler::CreatePluginHandlersL()
       
   403     {
       
   404     FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL()") ));
       
   405     if ( !iAtCmdExt.Handle() )
       
   406         {
       
   407         FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL() complete") ));
       
   408         User::Leave( KErrGeneral );
       
   409         }
       
   410     // First create the command reply pusher
       
   411     CDunAtCmdPusher* cmdPusher = CDunAtCmdPusher::NewLC( &iAtCmdExt,
       
   412                                                          this,
       
   413                                                          iDownstream,
       
   414                                                          &iOkBuffer );
       
   415     // Next create the URC handlers
       
   416     TInt i;
       
   417     TInt numOfPlugins = iAtCmdExt.NumberOfPlugins();
       
   418     for ( i=0; i<numOfPlugins; i++ )
       
   419         {
       
   420         AddOneUrcHandlerL();
       
   421         }
       
   422     CleanupStack::Pop( cmdPusher );
       
   423     iCmdPusher = cmdPusher;
       
   424     FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL() complete") ));
       
   425     }
       
   426 
       
   427 // ---------------------------------------------------------------------------
       
   428 // Creates an array of special commands
       
   429 // ---------------------------------------------------------------------------
       
   430 //
       
   431 void CDunAtCmdHandler::CreateSpecialCommandsL()
       
   432     {
       
   433     FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL()") ));
       
   434     TInt retTemp = KErrNone;
       
   435     TBool firstSearch = ETrue;
       
   436     for ( ;; )
       
   437         {
       
   438         retTemp = iAtCmdExt.GetNextSpecialCommand( iInputBuffer, firstSearch );
       
   439         if ( retTemp != KErrNone )
       
   440             {
       
   441             break;
       
   442             }
       
   443         HBufC8* specialCmd = HBufC8::NewMaxLC( iInputBuffer.Length() );
       
   444         TPtr8 specialCmdPtr = specialCmd->Des();
       
   445         specialCmdPtr.Copy( iInputBuffer );
       
   446         specialCmdPtr.UpperCase();
       
   447         iSpecials.AppendL( specialCmd );
       
   448         CleanupStack::Pop( specialCmd );
       
   449         }
       
   450     iInputBuffer.Zero();
       
   451     FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL() complete") ));
       
   452     }
       
   453 
       
   454 // ---------------------------------------------------------------------------
       
   455 // Recreates special command data.
       
   456 // This is done when a plugin is installed or uninstalled.
       
   457 // ---------------------------------------------------------------------------
       
   458 //
       
   459 TInt CDunAtCmdHandler::RecreateSpecialCommands()
       
   460     {
       
   461     FTRACE(FPrint( _L("CDunAtCmdHandler::RecreateSpecialCommands()") ));
       
   462     iSpecials.ResetAndDestroy();
       
   463     TRAPD( retTrap, CreateSpecialCommandsL() );
       
   464     FTRACE(FPrint( _L("CDunAtCmdHandler::RecreateSpecialCommands() complete") ));
       
   465     return retTrap;
       
   466     }
       
   467 
       
   468 // ---------------------------------------------------------------------------
       
   469 // Gets default settings from RATExtCommon and sets them to RATExt
       
   470 // ---------------------------------------------------------------------------
       
   471 //
       
   472 void CDunAtCmdHandler::GetAndSetDefaultSettingsL()
       
   473     {
       
   474     FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL()") ));
       
   475     // Note: Let's assume command mode is off by default
       
   476     TUint modeSet = GetCurrentModeL( KModeEcho | KModeQuiet | KModeVerbose );
       
   477     iEchoOn    = ( modeSet & KEchoModeBase    ) ? ETrue : EFalse;
       
   478     iQuietOn   = ( modeSet & KQuietModeBase   ) ? ETrue : EFalse;
       
   479     iVerboseOn = ( modeSet & KVerboseModeBase ) ? ETrue : EFalse;
       
   480     iCarriageReturn = GetCurrentModeL( KModeCarriage );
       
   481     iLineFeed = GetCurrentModeL( KModeLineFeed );
       
   482     iBackspace = GetCurrentModeL( KModeBackspace );
       
   483     iAtCmdExt.ReportQuietModeChange( iQuietOn );
       
   484     iAtCmdExt.ReportVerboseModeChange( iVerboseOn );
       
   485     iAtCmdExt.ReportCharacterChange( ECharTypeCarriage, iCarriageReturn );
       
   486     iAtCmdExt.ReportCharacterChange( ECharTypeLineFeed, iLineFeed );
       
   487     iAtCmdExt.ReportCharacterChange( ECharTypeBackspace, iBackspace );
       
   488     RegenerateReplyStrings();
       
   489     FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn ));
       
   490     FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() settings: CR=%u, LF=%u, BS=%u"), iCarriageReturn, iLineFeed, iBackspace ));
       
   491     FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() complete") ));
       
   492     }
       
   493 
       
   494 // ---------------------------------------------------------------------------
       
   495 // Regenerates the reply strings based on settings
       
   496 // ---------------------------------------------------------------------------
       
   497 //
       
   498 TBool CDunAtCmdHandler::RegenerateReplyStrings()
       
   499     {
       
   500     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateReplyStrings()") ));
       
   501     TBool retVal = EFalse;
       
   502     retVal |= RegenerateOkReply();
       
   503     retVal |= RegenerateErrorReply();
       
   504     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateReplyStrings() complete") ));
       
   505     return retVal;
       
   506     }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // Regenerates the ok reply based on settings
       
   510 // ---------------------------------------------------------------------------
       
   511 //
       
   512 TBool CDunAtCmdHandler::RegenerateOkReply()
       
   513     {
       
   514     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply()") ));
       
   515     iOkBuffer.Zero();
       
   516     if ( iQuietOn )
       
   517         {
       
   518         FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() (quiet) complete") ));
       
   519         return ETrue;
       
   520         }
       
   521     if ( iVerboseOn )
       
   522         {
       
   523         _LIT8( KVerboseOk, "OK" );
       
   524         iOkBuffer.Append( iCarriageReturn );
       
   525         iOkBuffer.Append( iLineFeed );
       
   526         iOkBuffer.Append( KVerboseOk );
       
   527         iOkBuffer.Append( iCarriageReturn );
       
   528         iOkBuffer.Append( iLineFeed );
       
   529         }
       
   530     else
       
   531         {
       
   532         _LIT8( KNumericOk, "0" );
       
   533         iOkBuffer.Append( KNumericOk );
       
   534         iOkBuffer.Append( iCarriageReturn );
       
   535         }
       
   536     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() complete") ));
       
   537     return EFalse;
       
   538     }
       
   539 
       
   540 // ---------------------------------------------------------------------------
       
   541 // Regenerates the error reply based on settings
       
   542 // ---------------------------------------------------------------------------
       
   543 //
       
   544 TBool CDunAtCmdHandler::RegenerateErrorReply()
       
   545     {
       
   546     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply()") ));
       
   547     iErrorBuffer.Zero();
       
   548     if ( iQuietOn )
       
   549         {
       
   550         FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() (quiet) complete") ));
       
   551         return ETrue;
       
   552         }
       
   553     if ( iVerboseOn )
       
   554         {
       
   555         _LIT8( KVerboseError, "ERROR" );
       
   556         iErrorBuffer.Append( iCarriageReturn );
       
   557         iErrorBuffer.Append( iLineFeed );
       
   558         iErrorBuffer.Append( KVerboseError );
       
   559         iErrorBuffer.Append( iCarriageReturn );
       
   560         iErrorBuffer.Append( iLineFeed );
       
   561         }
       
   562     else
       
   563         {
       
   564         _LIT8( KNumericError, "4" );
       
   565         iErrorBuffer.Append( KNumericError );
       
   566         iErrorBuffer.Append( iCarriageReturn );
       
   567         }
       
   568     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() complete") ));
       
   569     return EFalse;
       
   570     }
       
   571 
       
   572 // ---------------------------------------------------------------------------
       
   573 // Gets current mode
       
   574 // ---------------------------------------------------------------------------
       
   575 //
       
   576 TUint CDunAtCmdHandler::GetCurrentModeL( TUint aMask )
       
   577     {
       
   578     FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL()") ));
       
   579     TUint maskCheck = aMask & ( ~KSupportedModes );
       
   580     if ( maskCheck != 0 )
       
   581         {
       
   582         FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() (not supported) complete") ));
       
   583         User::Leave( KErrNotSupported );
       
   584         }
       
   585     TUint newMode = 0;
       
   586     TInt retTemp = iAtCmdExtCommon.GetMode( aMask, newMode );
       
   587     if ( retTemp != KErrNone )
       
   588         {
       
   589         FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() (ERROR) complete") ));
       
   590         User::Leave( retTemp );
       
   591         }
       
   592     FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() complete") ));
       
   593     return newMode & (KModeChanged-1);
       
   594     }
       
   595 
       
   596 // ---------------------------------------------------------------------------
       
   597 // Instantiates one URC message handling class instance and adds it to the URC
       
   598 // message handler array
       
   599 // ---------------------------------------------------------------------------
       
   600 //
       
   601 CDunAtUrcHandler* CDunAtCmdHandler::AddOneUrcHandlerL()
       
   602     {
       
   603     FTRACE(FPrint( _L("CDunAtCmdHandler::AddOneUrcHandlerL()") ));
       
   604     CDunAtUrcHandler* urcHandler = CDunAtUrcHandler::NewLC( &iAtCmdExt,
       
   605                                                             iDownstream );
       
   606     iUrcHandlers.AppendL( urcHandler );
       
   607     CleanupStack::Pop( urcHandler );
       
   608     FTRACE(FPrint( _L("CDunAtCmdHandler::AddOneUrcHandlerL() complete") ));
       
   609     return urcHandler;
       
   610     }
       
   611 
       
   612 // ---------------------------------------------------------------------------
       
   613 // Deletes all instantiated URC message handlers
       
   614 // ---------------------------------------------------------------------------
       
   615 //
       
   616 void CDunAtCmdHandler::DeletePluginHandlers()
       
   617     {
       
   618     FTRACE(FPrint( _L("CDunAtCmdHandler::DeletePluginHandlers()") ));
       
   619     delete iCmdPusher;
       
   620     iCmdPusher = NULL;
       
   621     TInt i;
       
   622     TInt count = iUrcHandlers.Count();
       
   623     for ( i=0; i<count; i++ )
       
   624         {
       
   625         delete iUrcHandlers[i];
       
   626         iUrcHandlers[i] = NULL;
       
   627         }
       
   628     iUrcHandlers.Reset();
       
   629     iUrcHandlers.Close();
       
   630     FTRACE(FPrint( _L("CDunAtCmdHandler::DeletePluginHandlers() complete") ));
       
   631     }
       
   632 
       
   633 // ---------------------------------------------------------------------------
       
   634 // Manages partial AT command
       
   635 // ---------------------------------------------------------------------------
       
   636 //
       
   637 TBool CDunAtCmdHandler::ManagePartialCommand( TDesC8& aCommand,
       
   638                                               TBool& aNeedsCarriage )
       
   639     {
       
   640     FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand()") ));
       
   641     aNeedsCarriage = ETrue;
       
   642     // Check length of command
       
   643     if ( aCommand.Length() == 0 )
       
   644         {
       
   645         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length zero) complete") ));
       
   646         return ETrue;
       
   647         }
       
   648     // Check one character (or unit) based input data
       
   649     if ( aCommand.Length() == KDunChSetMaxCharLen )
       
   650         {
       
   651         EchoCommand( aCommand );
       
   652         // Handle backspace and cancel characters
       
   653         TBool found = HandleSpecialCharacters( aCommand );
       
   654         if ( found )
       
   655             {
       
   656             FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (special) complete") ));
       
   657             return ETrue;
       
   658             }
       
   659         }
       
   660     TBool endFound = EFalse;
       
   661     TBool overflow = AppendCommandToInputBuffer( aCommand, endFound );
       
   662     if ( overflow )
       
   663         {
       
   664         // Overflow occurred so return ETrue (consumed) to skip all the rest
       
   665         // characters until carriage return is found
       
   666         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (overflow) complete") ));
       
   667         return ETrue;
       
   668         }
       
   669     // If something went wrong, do nothing (return consumed)
       
   670     if ( iInputBuffer.Length() <= 0 )
       
   671         {
       
   672         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length) complete") ));
       
   673         return ETrue;
       
   674         }
       
   675     // If "A/", no carriage return is needed, check that now
       
   676     if ( IsASlashCommand() )
       
   677         {
       
   678         aNeedsCarriage = EFalse;
       
   679         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (A/) complete") ));
       
   680         return EFalse;
       
   681         }
       
   682     // For other commands and if no end, just return with consumed
       
   683     if ( !endFound )
       
   684         {
       
   685         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (void) complete") ));
       
   686         return ETrue;
       
   687         }
       
   688     FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() complete") ));
       
   689     return EFalse;
       
   690     }
       
   691 
       
   692 // ---------------------------------------------------------------------------
       
   693 // Echoes a command if echo is on
       
   694 // ---------------------------------------------------------------------------
       
   695 //
       
   696 TBool CDunAtCmdHandler::EchoCommand( TDesC8& aDes )
       
   697     {
       
   698     FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand()") ));
       
   699     if ( aDes.Length() > KDunChSetMaxCharLen )
       
   700         {
       
   701         FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (wrong length) complete") ));
       
   702         return EFalse;
       
   703         }
       
   704     if ( iEchoOn )
       
   705         {
       
   706         iEchoBuffer.Copy( aDes );
       
   707         iDownstream->NotifyDataPushRequest( &iEchoBuffer, NULL );
       
   708         FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() complete") ));
       
   709         return ETrue;
       
   710         }
       
   711     FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (not started) complete") ));
       
   712     return EFalse;
       
   713     }
       
   714 
       
   715 // ---------------------------------------------------------------------------
       
   716 // Handles backspace and cancel characters
       
   717 // ---------------------------------------------------------------------------
       
   718 //
       
   719 TBool CDunAtCmdHandler::HandleSpecialCharacters( TDesC8& aCommand )
       
   720     {
       
   721     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters()") ));
       
   722     if ( aCommand.Length() != KDunChSetMaxCharLen )
       
   723         {
       
   724         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (wrong length) complete") ));
       
   725         return EFalse;
       
   726         }
       
   727     if ( aCommand[0] == iBackspace )
       
   728         {
       
   729         TInt bufferLength = iInputBuffer.Length();
       
   730         if ( bufferLength > 0 )
       
   731             {
       
   732             iInputBuffer.SetLength( bufferLength-1 );
       
   733             }
       
   734         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (backspace) complete") ));
       
   735         return ETrue;
       
   736         }
       
   737     if ( aCommand[0] == KDunCancel )
       
   738         {
       
   739         ResetParseBuffers();  // More processing here?
       
   740         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (cancel) complete") ));
       
   741         return ETrue;
       
   742         }
       
   743     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() complete") ));
       
   744     return EFalse;
       
   745     }
       
   746 
       
   747 // ---------------------------------------------------------------------------
       
   748 // Appends command to parse buffer
       
   749 // ---------------------------------------------------------------------------
       
   750 //
       
   751 TBool CDunAtCmdHandler::AppendCommandToInputBuffer( TDesC8& aCommand,
       
   752                                                     TBool& aEndFound )
       
   753     {
       
   754     FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer()") ));
       
   755     aEndFound = EFalse;
       
   756     TInt cmdBufIndex = 0;
       
   757     TInt cmdBufLim = aCommand.Length();
       
   758     while ( cmdBufIndex < cmdBufLim )
       
   759         {
       
   760         if ( iInputBuffer.Length() == iInputBuffer.MaxLength() )
       
   761             {
       
   762             // 1) If output is full and end found from input
       
   763             //    -> reset buffers and overflow found
       
   764             // 2) If output is full and end not found from input
       
   765             //    -> don't reset buffers and overflow found
       
   766             TInt foundIndex = FindEndOfCommand( aCommand );
       
   767             if ( foundIndex >= 0 )
       
   768                 {
       
   769                 aEndFound = ETrue;
       
   770                 ResetParseBuffers();
       
   771                 FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (reset) complete") ));
       
   772                 }
       
   773             FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (overflow) complete") ));
       
   774             return ETrue;
       
   775             }
       
   776         TChar character = aCommand[cmdBufIndex];
       
   777         if ( IsEndOfCommand(character) )
       
   778             {
       
   779             aEndFound = ETrue;
       
   780             iEndIndex = cmdBufIndex;
       
   781             break;
       
   782             }
       
   783         iInputBuffer.Append( aCommand[cmdBufIndex] );
       
   784         cmdBufIndex++;
       
   785         }
       
   786     FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() complete") ));
       
   787     return EFalse;
       
   788     }
       
   789 
       
   790 // ---------------------------------------------------------------------------
       
   791 // Handles next decoded command from input buffer
       
   792 // ---------------------------------------------------------------------------
       
   793 //
       
   794 TBool CDunAtCmdHandler::HandleNextDecodedCommand()
       
   795     {
       
   796     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand()") ));
       
   797     if ( iHandleState != EDunStateAtCmdHandling )
       
   798         {
       
   799         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (not ready) complete") ));
       
   800         return ETrue;
       
   801         }
       
   802     TBool extracted = ExtractNextDecodedCommand();
       
   803     if ( !extracted )
       
   804         {
       
   805         ManageEndOfCmdHandling( ETrue, ETrue, ETrue );
       
   806         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (last) complete") ));
       
   807         return ETrue;
       
   808         }
       
   809     // Next convert the decoded AT command to uppercase
       
   810     // Don't check for case status -> let mixed cases pass
       
   811     iParseInfo.iSendBuffer.Copy( iDecodeInfo.iDecodeBuffer );
       
   812     TInt maxLength = iParseInfo.iSendBuffer.MaxLength();
       
   813     TPtr8 upperDes( &iParseInfo.iSendBuffer[0], iParseInfo.iLimit, maxLength );
       
   814     upperDes.UpperCase();
       
   815     // Next always send the command to ATEXT
       
   816     iCmdPusher->IssueRequest( iParseInfo.iSendBuffer );
       
   817     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") ));
       
   818     return EFalse;
       
   819     }
       
   820 
       
   821 // ---------------------------------------------------------------------------
       
   822 // Finds the start of the next command
       
   823 // ---------------------------------------------------------------------------
       
   824 //
       
   825 TInt CDunAtCmdHandler::FindStartOfNextCommand()
       
   826     {
       
   827     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand()") ));
       
   828     // Note: here we need to avoid internal recursion when parsing the
       
   829     // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the
       
   830     // same upstream block.
       
   831     // Skip all the extra markers except the one we already know to exist.
       
   832     TInt i;
       
   833     TInt startVal = iEndIndex + 1;
       
   834     TInt foundIndex = KErrNotFound;
       
   835     TInt count = iCommand->Length();
       
   836     for ( i=startVal; i<count; i++ )
       
   837         {
       
   838         TChar character = (*iCommand)[i];
       
   839         if ( !(IsEndOfCommand(character)||IsDelimiterCharacter(character)) )
       
   840             {
       
   841             foundIndex = i;
       
   842             break;
       
   843             }
       
   844         }
       
   845     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand() complete") ));
       
   846     return foundIndex;
       
   847     }
       
   848 
       
   849 // ---------------------------------------------------------------------------
       
   850 // Manages end of AT command handling
       
   851 // ---------------------------------------------------------------------------
       
   852 //
       
   853 void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal,
       
   854                                                TBool aNotifyLocal,
       
   855                                                TBool aClearInput )
       
   856     {
       
   857     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") ));
       
   858     if ( iInputBuffer.Length() > 0 )
       
   859         {
       
   860         iLastBuffer.Copy( iInputBuffer );
       
   861         }
       
   862     ResetParseBuffers( aClearInput );
       
   863     iHandleState = EDunStateIdle;
       
   864     if ( aNotifyLocal )
       
   865         {
       
   866         iCmdPusher->SetEndOfCmdLine();
       
   867         }
       
   868     if ( !aNotifyExternal )
       
   869         {
       
   870         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") ));
       
   871         return;
       
   872         }
       
   873     TInt foundIndex = FindStartOfNextCommand();
       
   874     iUpstream->NotifyAtCmdHandlingEnd( foundIndex );
       
   875     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") ));
       
   876     }
       
   877 
       
   878 // ---------------------------------------------------------------------------
       
   879 // Extracts next decoded command from input buffer to decode buffer
       
   880 // ---------------------------------------------------------------------------
       
   881 //
       
   882 TBool CDunAtCmdHandler::ExtractNextDecodedCommand( TBool aPeek )
       
   883     {
       
   884     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") ));
       
   885     iParseInfo.iLimit = KErrNotFound;
       
   886     TDunDecodeInfo oldInfo = iDecodeInfo;
       
   887     iDecodeInfo.iDecodeBuffer.Zero();
       
   888     // Find start of decode command from input buffer
       
   889     TInt startIndex = iDecodeInfo.iDecodeIndex;
       
   890     startIndex = FindStartOfDecodedCommand( iInputBuffer, startIndex );
       
   891     if ( startIndex < 0 )
       
   892         {
       
   893         RestoreOldDecodeInfo( aPeek, oldInfo );
       
   894         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") ));
       
   895         return EFalse;
       
   896         }
       
   897     // Find end of decode command from input buffer
       
   898     TBool specialCmd = EFalse;
       
   899     TInt endIndex = KErrNotFound;
       
   900     specialCmd = CheckSpecialCommand( startIndex, endIndex );
       
   901     if ( !specialCmd )
       
   902         {
       
   903         FindSubCommand( startIndex, endIndex );
       
   904         }
       
   905     if ( endIndex < startIndex )
       
   906         {
       
   907         RestoreOldDecodeInfo( aPeek, oldInfo );
       
   908         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") ));
       
   909         return EFalse;
       
   910         }
       
   911     TInt cmdLength = endIndex - startIndex + 1;
       
   912     // If the limit was not already set then do it now
       
   913     if ( iParseInfo.iLimit < 0 )
       
   914         {
       
   915         iParseInfo.iLimit = cmdLength;
       
   916         }
       
   917     // Next create a new command
       
   918     if ( !iDecodeInfo.iFirstDecode && !specialCmd )
       
   919         {
       
   920         _LIT( KAtMsg, "AT" );
       
   921         iDecodeInfo.iDecodeBuffer.Append( KAtMsg );
       
   922         iParseInfo.iLimit += 2;  // Length of "AT"
       
   923         // Note: The length of iDecodeBuffer is not exceeded here because "AT"
       
   924         // is added only for the second commands after that.
       
   925         }
       
   926     TPtrC8 decodedCmd = iInputBuffer.Mid( startIndex, cmdLength );
       
   927     iDecodeInfo.iDecodeBuffer.Append( decodedCmd );
       
   928     // Set index for next round
       
   929     iDecodeInfo.iFirstDecode = EFalse;
       
   930     iDecodeInfo.iDecodeIndex = endIndex + 1;
       
   931     RestoreOldDecodeInfo( aPeek, oldInfo );
       
   932     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() complete") ));
       
   933     return ETrue;
       
   934     }
       
   935 
       
   936 // ---------------------------------------------------------------------------
       
   937 // Restores old decode info. For ExtractNextDecodedCommand() when aPeeks is
       
   938 // ETrue.
       
   939 // ---------------------------------------------------------------------------
       
   940 //
       
   941 void CDunAtCmdHandler::RestoreOldDecodeInfo( TBool aPeek,
       
   942                                              TDunDecodeInfo& aOldInfo )
       
   943     {
       
   944     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo()") ));
       
   945     if ( aPeek )
       
   946         {
       
   947         iEditorModeInfo.iPeekInfo = iDecodeInfo;
       
   948         iDecodeInfo = aOldInfo;
       
   949         }
       
   950     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") ));
       
   951     }
       
   952 
       
   953 // ---------------------------------------------------------------------------
       
   954 // Finds end of an AT command
       
   955 // ---------------------------------------------------------------------------
       
   956 //
       
   957 TInt CDunAtCmdHandler::FindEndOfCommand( TDesC8& aDes, TInt aStartIndex )
       
   958     {
       
   959     FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand()") ));
       
   960     TInt i;
       
   961     TInt length = aDes.Length();
       
   962     for ( i=aStartIndex; i<length; i++ )
       
   963         {
       
   964         TChar character = aDes[i];
       
   965         if ( IsEndOfCommand(character) )
       
   966             {
       
   967             FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand() complete (%d)"), i ));
       
   968             return i;
       
   969             }
       
   970         }
       
   971     FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand() (not found) complete") ));
       
   972     return KErrNotFound;
       
   973     }
       
   974 
       
   975 // ---------------------------------------------------------------------------
       
   976 // Tests for end of AT command character
       
   977 // ---------------------------------------------------------------------------
       
   978 //
       
   979 TBool CDunAtCmdHandler::IsEndOfCommand( TChar& aCharacter )
       
   980     {
       
   981     FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand()") ));
       
   982     if ( aCharacter==iCarriageReturn || aCharacter==iLineFeed )
       
   983         {
       
   984         FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (found) complete") ));
       
   985         return ETrue;
       
   986         }
       
   987     FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (not found) complete") ));
       
   988     return EFalse;
       
   989     }
       
   990 
       
   991 // ---------------------------------------------------------------------------
       
   992 // Finds start of a decoded AT command
       
   993 // ---------------------------------------------------------------------------
       
   994 //
       
   995 TInt CDunAtCmdHandler::FindStartOfDecodedCommand( TDesC8& aDes,
       
   996                                                   TInt aStartIndex )
       
   997     {
       
   998     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand()") ));
       
   999     TInt i;
       
  1000     TInt count = aDes.Length();
       
  1001     for ( i=aStartIndex; i<count; i++ )
       
  1002         {
       
  1003         TChar character = aDes[i];
       
  1004         if ( !IsDelimiterCharacter(character) )
       
  1005             {
       
  1006             FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand() complete (%d)"), i ));
       
  1007             return i;
       
  1008             }
       
  1009         }
       
  1010     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand() (not found) complete") ));
       
  1011     return KErrNotFound;
       
  1012     }
       
  1013 
       
  1014 // ---------------------------------------------------------------------------
       
  1015 // Checks if character is delimiter character
       
  1016 // ---------------------------------------------------------------------------
       
  1017 //
       
  1018 TBool CDunAtCmdHandler::IsDelimiterCharacter( TChar aCharacter )
       
  1019     {
       
  1020     FTRACE(FPrint( _L("CDunAtCmdHandler::IsDelimiterCharacter()") ));
       
  1021     if ( aCharacter.IsSpace() || aCharacter==';' || aCharacter==0x00 )
       
  1022         {
       
  1023         FTRACE(FPrint( _L("CDunAtCmdHandler::IsDelimiterCharacter() complete") ));
       
  1024         return ETrue;
       
  1025         }
       
  1026     FTRACE(FPrint( _L("CDunAtCmdHandler::IsDelimiterCharacter() (not delimiter) complete") ));
       
  1027     return EFalse;
       
  1028     }
       
  1029 
       
  1030 // ---------------------------------------------------------------------------
       
  1031 // Checks if character is of extended group
       
  1032 // ---------------------------------------------------------------------------
       
  1033 //
       
  1034 TBool CDunAtCmdHandler::IsExtendedCharacter( TChar aCharacter )
       
  1035     {
       
  1036     FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedCharacter()") ));
       
  1037     if ( aCharacter=='+'  || aCharacter=='&' || aCharacter=='%' ||
       
  1038          aCharacter=='\\' || aCharacter=='*' || aCharacter=='#' ||
       
  1039          aCharacter=='$'  || aCharacter=='^' )
       
  1040         {
       
  1041         FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedCharacter() complete") ));
       
  1042         return ETrue;
       
  1043         }
       
  1044     FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedCharacter() (not extended) complete") ));
       
  1045     return EFalse;
       
  1046     }
       
  1047 
       
  1048 // ---------------------------------------------------------------------------
       
  1049 // Checks special command
       
  1050 // ---------------------------------------------------------------------------
       
  1051 //
       
  1052 TBool CDunAtCmdHandler::CheckSpecialCommand( TInt aStartIndex,
       
  1053                                              TInt& aEndIndex )
       
  1054     {
       
  1055     FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand()") ));
       
  1056     TBuf8<KDunInputBufLength> upperBuf;
       
  1057     TInt newLength = iInputBuffer.Length() - aStartIndex;
       
  1058     upperBuf.Copy( &iInputBuffer[aStartIndex], newLength );
       
  1059     upperBuf.UpperCase();
       
  1060     TInt i;
       
  1061     TInt count = iSpecials.Count();
       
  1062     for ( i=0; i<count; i++ )
       
  1063         {
       
  1064         HBufC8* specialCmd = iSpecials[i];
       
  1065         TInt specialLength = specialCmd->Length();
       
  1066         if ( newLength < specialLength )
       
  1067             {
       
  1068             continue;
       
  1069             }
       
  1070         TInt origLength = newLength;
       
  1071         if ( newLength > specialLength )
       
  1072             {
       
  1073             upperBuf.SetLength( specialLength );
       
  1074             }
       
  1075         TInt cmpResult = upperBuf.Compare( *specialCmd );
       
  1076         upperBuf.SetLength( origLength );
       
  1077         if ( cmpResult == 0 )
       
  1078             {
       
  1079             iParseInfo.iLimit = specialLength;
       
  1080             aEndIndex = (origLength-1) + aStartIndex;
       
  1081             FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() complete") ));
       
  1082             return ETrue;
       
  1083             }
       
  1084         }
       
  1085     FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() (not found) complete") ));
       
  1086     return EFalse;
       
  1087     }
       
  1088 
       
  1089 // ---------------------------------------------------------------------------
       
  1090 // Saves character decode state for a found character
       
  1091 // ---------------------------------------------------------------------------
       
  1092 //
       
  1093 void CDunAtCmdHandler::SaveFoundCharDecodeState( TChar aCharacter,
       
  1094                                                  TBool aAddSpecial )
       
  1095     {
       
  1096     FTRACE(FPrint( _L("CDunAtCmdHandler::SaveFoundCharDecodeState()") ));
       
  1097     iDecodeInfo.iPrevExists = ETrue;
       
  1098     iDecodeInfo.iPrevChar = aCharacter;
       
  1099     if ( aAddSpecial )
       
  1100         {
       
  1101         iDecodeInfo.iSpecialFound =
       
  1102                 iAtSpecialCmdHandler->IsCompleteSubCommand( aCharacter );
       
  1103         }
       
  1104     FTRACE(FPrint( _L("CDunAtCmdHandler::SaveFoundCharDecodeState() complete") ));
       
  1105     }
       
  1106 
       
  1107 // ---------------------------------------------------------------------------
       
  1108 // Saves character decode state for a not found character
       
  1109 // ---------------------------------------------------------------------------
       
  1110 //
       
  1111 void CDunAtCmdHandler::SaveNotFoundCharDecodeState()
       
  1112     {
       
  1113     FTRACE(FPrint( _L("CDunAtCmdHandler::SaveNotFoundCharDecodeState()") ));
       
  1114     iDecodeInfo.iPrevExists = EFalse;
       
  1115     // Note: don't set iAssignFound or iInQuotes here
       
  1116     iDecodeInfo.iSpecialFound = EFalse;
       
  1117     FTRACE(FPrint( _L("CDunAtCmdHandler::SaveNotFoundCharDecodeState() complete") ));
       
  1118     }
       
  1119 
       
  1120 // ---------------------------------------------------------------------------
       
  1121 // Find quotes within subcommands
       
  1122 // ---------------------------------------------------------------------------
       
  1123 //
       
  1124 TBool CDunAtCmdHandler::FindSubCommandQuotes( TChar aCharacter,
       
  1125                                               TInt aStartIndex,
       
  1126                                               TInt& aEndIndex )
       
  1127     {
       
  1128     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes()") ));
       
  1129     if ( aCharacter == '"' )
       
  1130         {
       
  1131         if ( iParseInfo.iLimit < 0 )  // Only first the first '"'
       
  1132             {
       
  1133             iParseInfo.iLimit = aEndIndex - aStartIndex;
       
  1134             }
       
  1135         iDecodeInfo.iInQuotes ^= ETrue;  // EFalse to ETrue or ETrue to EFalse
       
  1136         SaveFoundCharDecodeState( aCharacter, EFalse );
       
  1137         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (quote) complete") ));
       
  1138         return ETrue;
       
  1139         }
       
  1140     // The next ones are those that are not in quotes.
       
  1141     // We still need to save the iParseInfo.iLimit and skip non-delimiter characters.
       
  1142     if ( aCharacter == '=' )
       
  1143         {
       
  1144         if ( iParseInfo.iLimit < 0 )  // Only first the first '"'
       
  1145             {
       
  1146             iParseInfo.iLimit = aEndIndex - aStartIndex;
       
  1147             }
       
  1148         iDecodeInfo.iAssignFound = ETrue;
       
  1149         SaveFoundCharDecodeState( aCharacter, EFalse );
       
  1150         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (equals) complete") ));
       
  1151         return ETrue;
       
  1152         }
       
  1153     if ( iDecodeInfo.iInQuotes )
       
  1154         {
       
  1155         SaveNotFoundCharDecodeState();
       
  1156         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (in quotes) complete") ));
       
  1157         return ETrue;
       
  1158         }
       
  1159     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (not found) complete") ));
       
  1160     return EFalse;
       
  1161     }
       
  1162 
       
  1163 // ---------------------------------------------------------------------------
       
  1164 // Check if in next subcommand's extended border
       
  1165 // ---------------------------------------------------------------------------
       
  1166 //
       
  1167 TBool CDunAtCmdHandler::IsExtendedBorder( TChar aCharacter,
       
  1168                                           TInt aStartIndex,
       
  1169                                           TInt& aEndIndex )
       
  1170     {
       
  1171     FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder()") ));
       
  1172     TInt expectedIndex = 0;  // "+CMD" when iDecodeInfo.iFirstDecode is EFalse
       
  1173     TInt extendedIndex = aEndIndex - aStartIndex;  // absolute index to the extended character
       
  1174     if ( iDecodeInfo.iFirstDecode )
       
  1175         {
       
  1176         expectedIndex = 2;  // "AT+CMD"
       
  1177         }
       
  1178     if ( extendedIndex == expectedIndex )
       
  1179         {
       
  1180         iDecodeInfo.iExtendedIndex = aEndIndex;
       
  1181         SaveFoundCharDecodeState( aCharacter );
       
  1182         FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (no border) complete") ));
       
  1183         return EFalse;
       
  1184         }
       
  1185     aEndIndex--;
       
  1186     FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (border) complete") ));
       
  1187     return ETrue;
       
  1188     }
       
  1189 
       
  1190 // ---------------------------------------------------------------------------
       
  1191 // Finds subcommand with alphanumeric borders
       
  1192 // ---------------------------------------------------------------------------
       
  1193 //
       
  1194 TBool CDunAtCmdHandler::FindSubCommandAlphaBorder( TChar aCharacter,
       
  1195                                                    TInt& aEndIndex )
       
  1196     {
       
  1197     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder()") ));
       
  1198     if ( iDecodeInfo.iAssignFound && !iDecodeInfo.iInQuotes )
       
  1199         {
       
  1200         // Check the special case when assigning a number with "basic" command
       
  1201         // and there is no delimiter after it. In this case <Numeric>|<Alpha>
       
  1202         // border must be detected but only for a "basic" command, not for
       
  1203         // extended.
       
  1204         if ( iDecodeInfo.iExtendedIndex<0    && iDecodeInfo.iPrevExists &&
       
  1205              iDecodeInfo.iPrevChar.IsDigit() && aCharacter.IsAlpha() )
       
  1206             {
       
  1207             aEndIndex--;
       
  1208             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (N|A) complete") ));
       
  1209             return ETrue;
       
  1210             }
       
  1211         // The code below is for the following type of cases:
       
  1212         // (do not check alphanumeric borders if "=" set without quotes):
       
  1213         // AT+CMD=a
       
  1214         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (skip) complete") ));
       
  1215         return EFalse;
       
  1216         }
       
  1217     if ( !iDecodeInfo.iPrevExists || !aCharacter.IsAlpha() )
       
  1218         {
       
  1219         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (not found) complete") ));
       
  1220         return EFalse;
       
  1221         }
       
  1222     if ( iDecodeInfo.iPrevChar.IsAlpha() )
       
  1223         {
       
  1224         // The check below detects the following type of cases
       
  1225         // (note that special handling is needed to separate the Alpha|Alpha boundary):
       
  1226         // AT&FE0
       
  1227         if ( iDecodeInfo.iSpecialFound )
       
  1228             {
       
  1229             // Special command was found before and this is Alpha|Alpha boundary -> end
       
  1230             aEndIndex--;
       
  1231             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (special) complete") ));
       
  1232             return ETrue;
       
  1233             }
       
  1234         // The code below is for the following type of cases
       
  1235         // (note there is no border between C|M, for example -> continue):
       
  1236         // ATCMD
       
  1237         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (continue) complete") ));
       
  1238         return EFalse;
       
  1239         }
       
  1240     // The code below is for skipping the following type of cases:
       
  1241     // AT+CMD [the '+' must be skipped]
       
  1242     if ( aEndIndex-1 == iDecodeInfo.iExtendedIndex )
       
  1243         {
       
  1244         FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (extended) complete") ));
       
  1245         return EFalse;
       
  1246         }
       
  1247     // The code below is for the following type of cases:
       
  1248     // ATCMD?ATCMD
       
  1249     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (boundary) complete") ));
       
  1250     aEndIndex--;
       
  1251     return ETrue;
       
  1252     }
       
  1253 
       
  1254 // ---------------------------------------------------------------------------
       
  1255 // Finds subcommand
       
  1256 // ---------------------------------------------------------------------------
       
  1257 //
       
  1258 TInt CDunAtCmdHandler::FindSubCommand( TInt aStartIndex, TInt& aEndIndex )
       
  1259     {
       
  1260     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand()") ));
       
  1261     aEndIndex = aStartIndex;
       
  1262     TBool found = EFalse;
       
  1263     TInt length = iInputBuffer.Length();
       
  1264     iDecodeInfo.iAssignFound = EFalse;
       
  1265     iDecodeInfo.iInQuotes = EFalse;
       
  1266     iDecodeInfo.iExtendedIndex = KErrNotFound;
       
  1267     SaveNotFoundCharDecodeState();
       
  1268     iAtSpecialCmdHandler->ResetComparisonBuffer();  // just to be sure
       
  1269     for ( ; aEndIndex<length; aEndIndex++ )
       
  1270         {
       
  1271         TChar character = iInputBuffer[aEndIndex];
       
  1272         found = FindSubCommandQuotes( character, aStartIndex, aEndIndex );
       
  1273         if ( found )
       
  1274             {
       
  1275             continue;
       
  1276             }
       
  1277         if ( character == '?' )
       
  1278             {
       
  1279             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (?) complete") ));
       
  1280             return KErrNone;
       
  1281             }
       
  1282         // The check below detects the following type of cases:
       
  1283         // ATCMD<delimiter>
       
  1284         if ( IsDelimiterCharacter(character) )
       
  1285             {
       
  1286             aEndIndex--;
       
  1287             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (delimiter) complete") ));
       
  1288             return KErrNone;
       
  1289             }
       
  1290         // The check below detects the following type of cases:
       
  1291         // ATCMD+CMD [first + as delimiter]
       
  1292         // AT+CMD+CMD [second + as delimiter]
       
  1293         if ( IsExtendedCharacter(character) )
       
  1294             {
       
  1295             found = IsExtendedBorder( character, aStartIndex, aEndIndex );
       
  1296             if ( !found )
       
  1297                 {
       
  1298                 continue;
       
  1299                 }
       
  1300             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (extended) complete") ));
       
  1301             return KErrNone;
       
  1302             }
       
  1303         found = FindSubCommandAlphaBorder( character, aEndIndex );
       
  1304         if ( found )
       
  1305             {
       
  1306             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (alpha sub) complete") ));
       
  1307             return KErrNone;
       
  1308             }
       
  1309         SaveFoundCharDecodeState( character );
       
  1310         }
       
  1311     aEndIndex--;
       
  1312     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (not found) complete") ));
       
  1313     return KErrNotFound;
       
  1314     }
       
  1315 
       
  1316 // ---------------------------------------------------------------------------
       
  1317 // Check if "A/" command
       
  1318 // ---------------------------------------------------------------------------
       
  1319 //
       
  1320 TBool CDunAtCmdHandler::IsASlashCommand()
       
  1321     {
       
  1322     FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand()") ));
       
  1323     if ( iInputBuffer.Length() == 2 )
       
  1324         {
       
  1325         if ( iInputBuffer[1] == '/' &&
       
  1326             (iInputBuffer[0] == 'A' || iInputBuffer[0] == 'a') )
       
  1327             {
       
  1328             FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (found) complete") ));
       
  1329             return ETrue;
       
  1330             }
       
  1331         }
       
  1332     FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (not found) complete") ));
       
  1333     return EFalse;
       
  1334     }
       
  1335 
       
  1336 // ---------------------------------------------------------------------------
       
  1337 // Handles "A/" command
       
  1338 // ---------------------------------------------------------------------------
       
  1339 //
       
  1340 TBool CDunAtCmdHandler::HandleASlashCommand()
       
  1341     {
       
  1342     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand()") ));
       
  1343     // If not "A/" command, return
       
  1344     if ( !IsASlashCommand() )
       
  1345         {
       
  1346         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (no push) complete") ));
       
  1347         return EFalse;
       
  1348         }
       
  1349     // If "A/" command and last buffer exist, set the last buffer as the current buffer
       
  1350     if ( iLastBuffer.Length() > 0 )
       
  1351         {
       
  1352         iInputBuffer.Copy( iLastBuffer );
       
  1353         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (copy) complete") ));
       
  1354         return EFalse;
       
  1355         }
       
  1356     // Last buffer not set so return "ERROR" if quiet mode not on
       
  1357     if ( iQuietOn )
       
  1358         {
       
  1359         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (quiet) complete") ));
       
  1360         return EFalse;
       
  1361         }
       
  1362     iDownstream->NotifyDataPushRequest( &iErrorBuffer, NULL );
       
  1363     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() complete") ));
       
  1364     return ETrue;
       
  1365     }
       
  1366 
       
  1367 // ---------------------------------------------------------------------------
       
  1368 // Resets parse buffers
       
  1369 // ---------------------------------------------------------------------------
       
  1370 //
       
  1371 void CDunAtCmdHandler::ResetParseBuffers( TBool aClearInput )
       
  1372     {
       
  1373     FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers()") ));
       
  1374     if ( aClearInput )
       
  1375         {
       
  1376         iInputBuffer.Zero();
       
  1377         }
       
  1378     iDecodeInfo.iFirstDecode = ETrue;
       
  1379     iDecodeInfo.iDecodeIndex = 0;
       
  1380     iDecodeInfo.iPrevExists = EFalse;
       
  1381     iDecodeInfo.iDecodeBuffer.Zero();
       
  1382     FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers() complete") ));
       
  1383     }
       
  1384 
       
  1385 // ---------------------------------------------------------------------------
       
  1386 // Manages command mode change
       
  1387 // ---------------------------------------------------------------------------
       
  1388 //
       
  1389 TBool CDunAtCmdHandler::ManageCommandModeChange( TUint aMode )
       
  1390     {
       
  1391     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange()" ) ));
       
  1392     if ( aMode & KCommandModeChanged )
       
  1393         {
       
  1394         if ( aMode & KModeCommand )  // command mode ON
       
  1395             {
       
  1396             ReportCommandModeChange( ETrue );
       
  1397             FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() command mode changed ON" ) ));
       
  1398             }
       
  1399         else  // command mode OFF
       
  1400             {
       
  1401             ReportCommandModeChange( EFalse );
       
  1402             FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() command mode changed OFF" ) ));
       
  1403             }
       
  1404         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() (change) complete" ) ));
       
  1405         return ETrue;
       
  1406         }
       
  1407     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange()" ) ));
       
  1408     return EFalse;
       
  1409     }
       
  1410 
       
  1411 // ---------------------------------------------------------------------------
       
  1412 // Reports command mode start/end change
       
  1413 // ---------------------------------------------------------------------------
       
  1414 //
       
  1415 void CDunAtCmdHandler::ReportCommandModeChange( TBool aStart )
       
  1416     {
       
  1417     FTRACE(FPrint( _L("CDunAtCmdHandler::ReportCommandModeChange()" ) ));
       
  1418     TInt i;
       
  1419     TInt count = iCmdCallbacks.Count();
       
  1420     if ( aStart )
       
  1421         {
       
  1422         if ( iDataMode )
       
  1423             {
       
  1424             for ( i=0; i<count; i++ )
       
  1425                 {
       
  1426                 iCmdCallbacks[i]->NotifyCommandModeStart();
       
  1427                 }
       
  1428             iDataMode = EFalse;
       
  1429             }
       
  1430         }
       
  1431     else  // end
       
  1432         {
       
  1433         if ( !iDataMode )
       
  1434             {
       
  1435             for ( i=0; i<count; i++ )
       
  1436                 {
       
  1437                 iCmdCallbacks[i]->NotifyCommandModeEnd();
       
  1438                 }
       
  1439             iDataMode = ETrue;
       
  1440             }
       
  1441         }
       
  1442     FTRACE(FPrint( _L("CDunAtCmdHandler::ReportCommandModeChange() complete" ) ));
       
  1443     }
       
  1444 
       
  1445 // ---------------------------------------------------------------------------
       
  1446 // Manages echo mode change
       
  1447 // ---------------------------------------------------------------------------
       
  1448 //
       
  1449 TBool CDunAtCmdHandler::ManageEchoModeChange( TUint aMode )
       
  1450     {
       
  1451     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange()" ) ));
       
  1452     if ( aMode & KEchoModeChanged )
       
  1453         {
       
  1454         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() checking echo mode..." ) ));
       
  1455         if ( aMode & KModeEcho )  // echo mode ON
       
  1456             {
       
  1457             iEchoOn = ETrue;
       
  1458             FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() echo mode changed ON" ) ));
       
  1459             }
       
  1460         else  // echo mode OFF
       
  1461             {
       
  1462             iEchoOn = EFalse;
       
  1463             FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() echo mode changed OFF" ) ));
       
  1464             }
       
  1465         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() (change) complete" ) ));
       
  1466         return ETrue;
       
  1467         }
       
  1468     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() complete" ) ));
       
  1469     return EFalse;
       
  1470     }
       
  1471 
       
  1472 // ---------------------------------------------------------------------------
       
  1473 // Manages quiet mode change
       
  1474 // ---------------------------------------------------------------------------
       
  1475 //
       
  1476 TBool CDunAtCmdHandler::ManageQuietModeChange( TUint aMode )
       
  1477     {
       
  1478     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange()" ) ));
       
  1479     if ( aMode & KQuietModeChanged )
       
  1480         {
       
  1481         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() checking quiet mode..." ) ));
       
  1482         if ( aMode & KModeQuiet )  // quiet mode ON
       
  1483             {
       
  1484             iAtCmdExt.ReportQuietModeChange( ETrue );
       
  1485             iQuietOn = ETrue;
       
  1486             FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() quiet mode changed ON" ) ));
       
  1487             }
       
  1488         else  // quiet mode OFF
       
  1489             {
       
  1490             iAtCmdExt.ReportQuietModeChange( EFalse );
       
  1491             iQuietOn = EFalse;
       
  1492             FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() quiet mode changed OFF" ) ));
       
  1493             }
       
  1494         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() (change) complete" ) ));
       
  1495         return ETrue;
       
  1496         }
       
  1497     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() complete" ) ));
       
  1498     return EFalse;
       
  1499     }
       
  1500 
       
  1501 // ---------------------------------------------------------------------------
       
  1502 // Manages quiet mode change
       
  1503 // ---------------------------------------------------------------------------
       
  1504 //
       
  1505 TBool CDunAtCmdHandler::ManageVerboseModeChange( TUint aMode )
       
  1506     {
       
  1507     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange()" ) ));
       
  1508     if ( aMode & KVerboseModeChanged )
       
  1509         {
       
  1510         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() checking verbose mode..." ) ));
       
  1511         if ( aMode & KModeVerbose )  // verbose mode ON
       
  1512             {
       
  1513             iAtCmdExt.ReportVerboseModeChange( ETrue );
       
  1514             iVerboseOn = ETrue;
       
  1515             FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyVerboseStatusChange() verbose mode changed ON" ) ));
       
  1516             }
       
  1517         else  // verbose mode OFF
       
  1518             {
       
  1519             iAtCmdExt.ReportVerboseModeChange( EFalse );
       
  1520             iVerboseOn = EFalse;
       
  1521             FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyVerboseStatusChange() verbose mode changed OFF" ) ));
       
  1522             }
       
  1523         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() (change) complete" ) ));
       
  1524         return ETrue;
       
  1525         }
       
  1526     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() complete" ) ));
       
  1527     return EFalse;
       
  1528     }
       
  1529 
       
  1530 // ---------------------------------------------------------------------------
       
  1531 // Manages character change
       
  1532 // ---------------------------------------------------------------------------
       
  1533 //
       
  1534 void CDunAtCmdHandler::ManageCharacterChange( TUint aMode )
       
  1535     {
       
  1536     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange()" ) ));
       
  1537     if ( aMode & KCarriageChanged )
       
  1538         {
       
  1539         iCarriageReturn = aMode & (KModeChanged-1);
       
  1540         iAtCmdExt.ReportCharacterChange( ECharTypeCarriage, iCarriageReturn );
       
  1541         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() carriage return changed" ) ));
       
  1542         }
       
  1543     else if ( aMode & KLineFeedChanged )
       
  1544         {
       
  1545         iLineFeed = aMode & (KModeChanged-1);
       
  1546         iAtCmdExt.ReportCharacterChange( ECharTypeLineFeed, iLineFeed );
       
  1547         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() line feed changed" ) ));
       
  1548         }
       
  1549     else if ( aMode & KBackspaceChanged )
       
  1550         {
       
  1551         iBackspace = aMode & (KModeChanged-1);
       
  1552         iAtCmdExt.ReportCharacterChange( ECharTypeBackspace, iBackspace );
       
  1553         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() backspace changed" ) ));
       
  1554         }
       
  1555     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() complete" ) ));
       
  1556     }
       
  1557 
       
  1558 // ---------------------------------------------------------------------------
       
  1559 // Manages editor mode reply
       
  1560 // ---------------------------------------------------------------------------
       
  1561 //
       
  1562 TInt CDunAtCmdHandler::ManageEditorModeReply( TBool aStart )
       
  1563     {
       
  1564     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply()" ) ));
       
  1565     // Two modes possible here:
       
  1566     // 1) Sending data directly from DTE to DCE, i.e. no subsequent data in
       
  1567     //    the input buffer -> Reissue read request from DTE.
       
  1568     // 2) Sending data from input buffer to DCE -> Do not reissue read request
       
  1569     //    from DTE: send the data in a loop
       
  1570     // In summary: send data byte-by-byte in editor mode until end of input.
       
  1571     // When end of input notify CDunUpstream to reissue the read request.
       
  1572     TBool nextContentFound = FindNextContent( aStart );
       
  1573     if ( !nextContentFound )
       
  1574         {
       
  1575         iUpstream->NotifyEditorModeReply( aStart );
       
  1576         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") ));
       
  1577         return KErrNone;
       
  1578         }
       
  1579     // In block mode end the block mode by sending <ESC> and hope it works.
       
  1580     iEscapeBuffer.Zero();
       
  1581     iEscapeBuffer.Append( KDunEscape );
       
  1582     iCmdPusher->IssueRequest( iEscapeBuffer, EFalse );
       
  1583     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply() complete" ) ));
       
  1584     return KErrNone;
       
  1585     }
       
  1586 
       
  1587 // ---------------------------------------------------------------------------
       
  1588 // Finds the next content from the input data
       
  1589 // ---------------------------------------------------------------------------
       
  1590 //
       
  1591 TBool CDunAtCmdHandler::FindNextContent( TBool aStart )
       
  1592     {
       
  1593     FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent()" ) ));
       
  1594     if ( !aStart )
       
  1595         {
       
  1596         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (skip) complete" ) ));
       
  1597         return iEditorModeInfo.iContentFound;
       
  1598         }
       
  1599     iEditorModeInfo.iContentFound = EFalse;
       
  1600     TInt foundCmdIndex = KErrNotFound;
       
  1601     TBool nextContentFound = ExtractNextDecodedCommand( ETrue );  // peek
       
  1602     if ( !nextContentFound )
       
  1603         {
       
  1604         // Check the next subblock
       
  1605         foundCmdIndex = FindStartOfNextCommand();
       
  1606         }
       
  1607     if ( !nextContentFound && foundCmdIndex<0 )
       
  1608         {
       
  1609         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (not found) complete") ));
       
  1610         return EFalse;
       
  1611         }
       
  1612     iEditorModeInfo.iContentFound = ETrue;
       
  1613     FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() complete" ) ));
       
  1614     return ETrue;
       
  1615     }
       
  1616 
       
  1617 // ---------------------------------------------------------------------------
       
  1618 // From class MDunAtCmdPusher.
       
  1619 // Notifies about end of AT command processing. This is after all reply data
       
  1620 // for an AT command is multiplexed to the downstream.
       
  1621 // ---------------------------------------------------------------------------
       
  1622 //
       
  1623 TInt CDunAtCmdHandler::NotifyEndOfProcessing( TInt /*aError*/ )
       
  1624     {
       
  1625     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing()" ) ));
       
  1626     TBool editorMode = iCmdPusher->EditorMode();
       
  1627     if ( editorMode )
       
  1628         {
       
  1629         ManageEditorModeReply( ETrue );
       
  1630         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() (editor) complete" ) ));
       
  1631         return KErrNone;
       
  1632         }
       
  1633     HandleNextDecodedCommand();
       
  1634     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) ));
       
  1635     return KErrNone;
       
  1636     }
       
  1637 
       
  1638 // ---------------------------------------------------------------------------
       
  1639 // From class MDunAtCmdPusher.
       
  1640 // Notifies about request to stop AT command handling for the rest of the
       
  1641 // command line data
       
  1642 // ---------------------------------------------------------------------------
       
  1643 //
       
  1644 TInt CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()
       
  1645     {
       
  1646     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()" ) ));
       
  1647     TInt retVal = Stop();
       
  1648     ManageEndOfCmdHandling( ETrue, EFalse, ETrue );
       
  1649     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() complete" ) ));
       
  1650     return retVal;
       
  1651     }
       
  1652 
       
  1653 // ---------------------------------------------------------------------------
       
  1654 // From class MDunAtCmdPusher.
       
  1655 // Notifies about request to peek for the next command
       
  1656 // ---------------------------------------------------------------------------
       
  1657 //
       
  1658 TBool CDunAtCmdHandler::NotifyNextCommandPeekRequest()
       
  1659     {
       
  1660     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") ));
       
  1661     TBool extracted = ExtractNextDecodedCommand( ETrue );
       
  1662     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") ));
       
  1663     return extracted;
       
  1664     }
       
  1665 
       
  1666 // ---------------------------------------------------------------------------
       
  1667 // From class MDunAtCmdPusher.
       
  1668 // Notifies about editor mode reply
       
  1669 // ---------------------------------------------------------------------------
       
  1670 //
       
  1671 TInt CDunAtCmdHandler::NotifyEditorModeReply()
       
  1672     {
       
  1673     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply()") ));
       
  1674     TInt retVal = ManageEditorModeReply( EFalse );
       
  1675     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") ));
       
  1676     return retVal;
       
  1677     }
       
  1678 
       
  1679 // ---------------------------------------------------------------------------
       
  1680 // From class MDunAtEcomListen.
       
  1681 // Notifies about new plugin installation
       
  1682 // ---------------------------------------------------------------------------
       
  1683 //
       
  1684 TInt CDunAtCmdHandler::NotifyPluginInstallation( TUid& /*aPluginUid*/ )
       
  1685     {
       
  1686     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation()" ) ));
       
  1687     CDunAtUrcHandler* urcHandler = NULL;
       
  1688     TRAPD( retTrap, urcHandler=AddOneUrcHandlerL() );
       
  1689     if ( retTrap != KErrNone )
       
  1690         {
       
  1691         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (trapped!) complete" ) ));
       
  1692         return retTrap;
       
  1693         }
       
  1694     TInt retTemp = urcHandler->IssueRequest();
       
  1695     if ( retTemp != KErrNone )
       
  1696         {
       
  1697         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (issuerequest) complete" ) ));
       
  1698         return retTemp;
       
  1699         }
       
  1700     TUid ownerUid = urcHandler->OwnerUid();
       
  1701     iAtCmdExt.ReportListenerUpdateReady( ownerUid, EEcomTypeInstall );
       
  1702     // As a last step recreate the special command data
       
  1703     retTemp = RecreateSpecialCommands();
       
  1704     if ( retTemp != KErrNone )
       
  1705         {
       
  1706         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (recreate) complete" ) ));
       
  1707         return retTemp;
       
  1708         }
       
  1709     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() complete" ) ));
       
  1710     return KErrNone;
       
  1711     }
       
  1712 
       
  1713 // ---------------------------------------------------------------------------
       
  1714 // From class MDunAtEcomListen.
       
  1715 // Notifies about existing plugin uninstallation
       
  1716 // ---------------------------------------------------------------------------
       
  1717 //
       
  1718 TInt CDunAtCmdHandler::NotifyPluginUninstallation( TUid& aPluginUid )
       
  1719     {
       
  1720     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation()" ) ));
       
  1721     TInt i;
       
  1722     TInt count = iUrcHandlers.Count();
       
  1723     for ( i=count-1; i>=0; i-- )
       
  1724         {
       
  1725         TUid ownerUid = iUrcHandlers[i]->OwnerUid();
       
  1726         if ( ownerUid == aPluginUid )
       
  1727             {
       
  1728             delete iUrcHandlers[i];
       
  1729             iUrcHandlers.Remove( i );
       
  1730             iAtCmdExt.ReportListenerUpdateReady( ownerUid,
       
  1731                                                  EEcomTypeUninstall );
       
  1732             }
       
  1733         }
       
  1734     // As a last step recreate the special command data
       
  1735     TInt retTemp = RecreateSpecialCommands();
       
  1736     if ( retTemp != KErrNone )
       
  1737         {
       
  1738         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation() (recreate) complete" ) ));
       
  1739         return retTemp;
       
  1740         }
       
  1741     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation() complete" ) ));
       
  1742     return KErrNone;
       
  1743     }
       
  1744 
       
  1745 // ---------------------------------------------------------------------------
       
  1746 // From class MDunAtModeListen.
       
  1747 // Gets called on mode status change
       
  1748 // ---------------------------------------------------------------------------
       
  1749 //
       
  1750 TInt CDunAtCmdHandler::NotifyModeStatusChange( TUint aMode )
       
  1751     {
       
  1752     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange()") ));
       
  1753     TBool commandModeSet = ManageCommandModeChange( aMode );
       
  1754     TBool echoModeSet = ManageEchoModeChange( aMode );
       
  1755     TBool quietModeSet = ManageQuietModeChange( aMode );
       
  1756     TBool verboseModeSet = ManageVerboseModeChange( aMode );
       
  1757     if ( quietModeSet || verboseModeSet )
       
  1758         {
       
  1759         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn ));
       
  1760         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() (regenerate) mode set" ) ));
       
  1761         RegenerateReplyStrings();
       
  1762         return KErrNone;
       
  1763         }
       
  1764     // Keep the following after "quietModeSet || verboseModeSet" in order to
       
  1765     // regenerate the reply also if two modes change at the same time
       
  1766     if ( commandModeSet || echoModeSet )
       
  1767         {
       
  1768         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn ));
       
  1769         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() mode set" ) ));
       
  1770         return KErrNone;
       
  1771         }
       
  1772     ManageCharacterChange( aMode );
       
  1773     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: CR=%u, LF=%u, BS=%u"), iCarriageReturn, iLineFeed, iBackspace ));
       
  1774     RegenerateReplyStrings();
       
  1775     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() complete") ));
       
  1776     return KErrNone;
       
  1777     }