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