localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp
changeset 33 883e91c086aa
parent 28 85e0c0339cc3
child 38 48c22c726cf9
equal deleted inserted replaced
28:85e0c0339cc3 33:883e91c086aa
    21  *   Thus the ATEXT plugins don't need to check for case. The conversion to
    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.
    22  *   upper case form stops when carriage return or '=' character is found.
    23  */
    23  */
    24 
    24 
    25 /*
    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 /*
    26  * The AT command handling is splitted to two parts on high level:
    44  * The AT command handling is splitted to two parts on high level:
    27  * 1) Splitter: splitting the sub-commands in a command line to multiple ones
    45  * 1) Splitter: splitting the sub-commands in a command line to multiple ones
    28  *    for ATEXT to process.
    46  *    for ATEXT to process.
    29  * 2) Combiner: combining the replies coming from ATEXT using a filter
    47  * 2) Combiner: combining the replies coming from ATEXT using a filter
    30  *    (the filter categories are explained in DunAtCmdPusher.cpp)
    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.
    31  */
    56  */
    32 
    57 
    33 #include "DunAtCmdHandler.h"
    58 #include "DunAtCmdHandler.h"
    34 #include "DunAtUrcHandler.h"
    59 #include "DunAtUrcHandler.h"
    35 #include "DunDownstream.h"
    60 #include "DunDownstream.h"
   137     FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() complete" ) ));
   162     FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() complete" ) ));
   138     return KErrNone;
   163     return KErrNone;
   139     }
   164     }
   140 
   165 
   141 // ---------------------------------------------------------------------------
   166 // ---------------------------------------------------------------------------
   142 // Parses an AT command
   167 // Adds data for parsing and parses if necessary
   143 // ---------------------------------------------------------------------------
   168 // ---------------------------------------------------------------------------
   144 //
   169 //
   145 EXPORT_C TInt CDunAtCmdHandler::ParseCommand( TDesC8& aCommand,
   170 EXPORT_C TInt CDunAtCmdHandler::AddDataForParsing( TDesC8& aInput,
   146                                               TBool& aPartialInput )
   171                                                    TBool& aMoreNeeded )
   147     {
   172     {
   148     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") ));
   173     FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing()") ));
   149     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") ));
   174     FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() received (%d bytes):"), aInput.Length() ));
   150     FTRACE(FPrintRaw(aCommand) );
   175     FTRACE(FPrintRaw(aInput) );
   151     TBool editorMode = iCmdPusher->EditorMode();
   176     TBool editorMode = iCmdPusher->EditorMode();
   152     if ( editorMode )
   177     if ( editorMode )
   153         {
   178         {
   154         // Note: return here with "no partial input" and some error to fool
   179         // Note: return here with "no more data needed" and some error to fool
   155         // CDunUpstream into not reissuing the read request.
   180         // CDunUpstream into not reissuing the read request.
   156         iCmdPusher->IssueRequest( aCommand, EFalse );
   181         iCmdPusher->IssueRequest( aInput, EFalse );
   157         aPartialInput = EFalse;
   182         aMoreNeeded = EFalse;
   158         return KErrGeneral;
   183         return KErrGeneral;
   159         }
   184         }
   160     iCommand = &aCommand;  // iCommand only for normal mode
   185     iInput = &aInput;  // iInput only for normal mode
   161     // Manage partial AT command
   186     // Manage partial AT command
   162     TBool needsCarriage = ETrue;
   187     TBool moreNeeded = ManagePartialCommand();
   163     TBool okToExit = ManagePartialCommand( aCommand, needsCarriage );
   188     if ( moreNeeded )
   164     if ( okToExit )
   189         {
   165         {
   190         aMoreNeeded = ETrue;
   166         FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (ok to exit) complete") ));
   191         FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() (more partial) complete") ));
   167         aPartialInput = ETrue;
       
   168         return KErrNone;
   192         return KErrNone;
   169         }
   193         }
   170     if ( iHandleState != EDunStateIdle )
   194     if ( iHandleState != EDunStateIdle )
   171         {
   195         {
   172         aPartialInput = EFalse;
   196         aMoreNeeded = EFalse;
   173         ResetParseBuffers();
   197         ManageEndOfCmdHandling( EFalse, EFalse );
   174         FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not ready) complete") ));
   198         FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() (not ready) complete") ));
   175         return KErrNotReady;
   199         return KErrNotReady;
   176         }
   200         }
   177     TBool pushStarted = HandleASlashCommand();
   201     TBool pushStarted = HandleASlashCommand();
   178     if ( pushStarted )
   202     if ( pushStarted )
   179         {
   203         {
   180         // Note: return here with "partial input" status to fool CDunUpstream
   204         // Note: return here with "partial input" status to fool CDunUpstream
   181         // into reissuing the read request. The AT command has not really
   205         // into reissuing the read request. The AT command has not really
   182         // started yet so this is necessary.
   206         // started yet so this is necessary.
   183         aPartialInput = ETrue;
   207         aMoreNeeded = ETrue;
   184         ResetParseBuffers();
   208         ManageEndOfCmdHandling( EFalse, EFalse );
   185         FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (A/) complete") ));
   209         FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() (A/) complete") ));
   186         return KErrNone;
   210         return KErrNone;
   187         }
   211         }
   188     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received total:") ));
       
   189     FTRACE(FPrintRaw(iInputBuffer) );
       
   190     iHandleState = EDunStateAtCmdHandling;
   212     iHandleState = EDunStateAtCmdHandling;
   191     iUpstream->NotifyAtCmdHandlingStart();
       
   192     iDecodeInfo.iFirstDecode = ETrue;
   213     iDecodeInfo.iFirstDecode = ETrue;
   193     iDecodeInfo.iDecodeIndex = 0;
   214     iDecodeInfo.iDecodeIndex = 0;
   194     HandleNextDecodedCommand();
   215     iDecodeInfo.iPrevExists = EFalse;
   195     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() complete") ));
   216     iParseInfo.iLimit = KErrNotFound;
   196     aPartialInput = EFalse;
   217     iParseInfo.iSendBuffer.Zero();
       
   218     iEditorModeInfo.iContentFound = EFalse;
       
   219     HandleNextSubCommand();
       
   220     FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() complete") ));
       
   221     aMoreNeeded = EFalse;
   197     return KErrNone;
   222     return KErrNone;
   198     }
   223     }
   199 
   224 
   200 // ---------------------------------------------------------------------------
   225 // ---------------------------------------------------------------------------
   201 // Manages request to abort command handling
   226 // Manages request to abort command handling
   209     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest() complete") ));
   234     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest() complete") ));
   210     return retVal;
   235     return retVal;
   211     }
   236     }
   212 
   237 
   213 // ---------------------------------------------------------------------------
   238 // ---------------------------------------------------------------------------
   214 // Sets end of command line marker on for the possible series of AT commands.
       
   215 // ---------------------------------------------------------------------------
       
   216 //
       
   217 EXPORT_C void CDunAtCmdHandler::SetEndOfCmdLine( TBool aClearInput )
       
   218     {
       
   219     FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine()") ));
       
   220     ManageEndOfCmdHandling( EFalse, ETrue, aClearInput );
       
   221     FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") ));
       
   222     }
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 // Sends a character to be echoed
   239 // Sends a character to be echoed
   226 // ---------------------------------------------------------------------------
   240 // ---------------------------------------------------------------------------
   227 //
   241 //
   228 EXPORT_C TInt CDunAtCmdHandler::SendEchoCharacter( const TDesC8* aInput,
   242 EXPORT_C TInt CDunAtCmdHandler::SendEchoCharacter( const TDesC8* aInput,
   229                                                    MDunAtCmdEchoer* aCallback )
   243                                                    MDunAtCmdEchoer* aCallback )
   248         return KErrNotReady;
   262         return KErrNotReady;
   249         }
   263         }
   250     iCmdPusher->Stop();
   264     iCmdPusher->Stop();
   251     // The line below is used in the case when this function is called by
   265     // The line below is used in the case when this function is called by
   252     // CDunUpstream as a result of "data mode ON" change notification.
   266     // CDunUpstream as a result of "data mode ON" change notification.
   253     // In this case it is possible that HandleNextDecodedCommand() returns
   267     // In this case it is possible that HandleNextSubCommand() returns
   254     // without resetting the iInputBuffer because of the way it checks the
   268     // without resetting the iSendBuffer because of the way it checks the
   255     // iHandleState.
   269     // iHandleState.
   256     ManageEndOfCmdHandling( EFalse, ETrue, ETrue );
   270     ManageEndOfCmdHandling( ETrue, EFalse );
   257     FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") ));
   271     FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") ));
   258     return KErrNone;
   272     return KErrNone;
   259     }
   273     }
   260 
   274 
   261 // ---------------------------------------------------------------------------
   275 // ---------------------------------------------------------------------------
   372     // Don't initialize iConnectionName here (it is set through NewL)
   386     // Don't initialize iConnectionName here (it is set through NewL)
   373     iHandleState = EDunStateIdle;
   387     iHandleState = EDunStateIdle;
   374     iCarriageReturn = 0;
   388     iCarriageReturn = 0;
   375     iLineFeed = 0;
   389     iLineFeed = 0;
   376     iBackspace = 0;
   390     iBackspace = 0;
   377     iCommand = NULL;
   391     iInput = NULL;
   378     iDecodeInfo.iFirstDecode = ETrue;
   392     iDecodeInfo.iFirstDecode = ETrue;
   379     iDecodeInfo.iDecodeIndex = KErrNotFound;
   393     iDecodeInfo.iDecodeIndex = KErrNotFound;
   380     iDecodeInfo.iExtendedIndex = KErrNotFound;
   394     iDecodeInfo.iExtendedIndex = KErrNotFound;
   381     iDecodeInfo.iPrevChar = 0;
   395     iDecodeInfo.iPrevChar = 0;
   382     iDecodeInfo.iPrevExists = EFalse;
   396     iDecodeInfo.iPrevExists = EFalse;
   383     iDecodeInfo.iAssignFound = EFalse;
   397     iDecodeInfo.iAssignFound = EFalse;
   384     iDecodeInfo.iInQuotes = EFalse;
   398     iDecodeInfo.iInQuotes = EFalse;
   385     iDecodeInfo.iSpecialFound = EFalse;
   399     iDecodeInfo.iSpecialFound = EFalse;
       
   400     iDecodeInfo.iCmdsHandled = 0;
   386     iEditorModeInfo.iContentFound = EFalse;
   401     iEditorModeInfo.iContentFound = EFalse;
   387     iCmdPusher = NULL;
   402     iCmdPusher = NULL;
   388     iEcomListen = NULL;
   403     iEcomListen = NULL;
   389     iModeListen = NULL;
   404     iModeListen = NULL;
   390     iNvramListen = NULL;
   405     iNvramListen = NULL;
   433     FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL()") ));
   448     FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL()") ));
   434     TInt retTemp = KErrNone;
   449     TInt retTemp = KErrNone;
   435     TBool firstSearch = ETrue;
   450     TBool firstSearch = ETrue;
   436     for ( ;; )
   451     for ( ;; )
   437         {
   452         {
   438         retTemp = iAtCmdExt.GetNextSpecialCommand( iInputBuffer, firstSearch );
   453         // Let's borrow iLineBuffer for this purpose
       
   454         retTemp = iAtCmdExt.GetNextSpecialCommand( iLineBuffer, firstSearch );
   439         if ( retTemp != KErrNone )
   455         if ( retTemp != KErrNone )
   440             {
   456             {
   441             break;
   457             break;
   442             }
   458             }
   443         HBufC8* specialCmd = HBufC8::NewMaxLC( iInputBuffer.Length() );
   459         TInt lineLength = iLineBuffer.Length();
   444         TPtr8 specialCmdPtr = specialCmd->Des();
   460         HBufC8* specialCmd = HBufC8::NewMaxLC( lineLength );
   445         specialCmdPtr.Copy( iInputBuffer );
   461         *specialCmd = iLineBuffer;
   446         specialCmdPtr.UpperCase();
       
   447         iSpecials.AppendL( specialCmd );
   462         iSpecials.AppendL( specialCmd );
   448         CleanupStack::Pop( specialCmd );
   463         CleanupStack::Pop( specialCmd );
   449         }
   464         }
   450     iInputBuffer.Zero();
   465     iLineBuffer.Zero();
   451     FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL() complete") ));
   466     FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL() complete") ));
   452     }
   467     }
   453 
   468 
   454 // ---------------------------------------------------------------------------
   469 // ---------------------------------------------------------------------------
   455 // Recreates special command data.
   470 // Recreates special command data.
   510 // ---------------------------------------------------------------------------
   525 // ---------------------------------------------------------------------------
   511 //
   526 //
   512 TBool CDunAtCmdHandler::RegenerateOkReply()
   527 TBool CDunAtCmdHandler::RegenerateOkReply()
   513     {
   528     {
   514     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply()") ));
   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         }
   515     iOkBuffer.Zero();
   535     iOkBuffer.Zero();
   516     if ( iQuietOn )
   536     if ( iQuietOn )
   517         {
   537         {
   518         FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() (quiet) complete") ));
   538         FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() (quiet) complete") ));
   519         return ETrue;
   539         return ETrue;
   542 // ---------------------------------------------------------------------------
   562 // ---------------------------------------------------------------------------
   543 //
   563 //
   544 TBool CDunAtCmdHandler::RegenerateErrorReply()
   564 TBool CDunAtCmdHandler::RegenerateErrorReply()
   545     {
   565     {
   546     FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply()") ));
   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         }
   547     iErrorBuffer.Zero();
   572     iErrorBuffer.Zero();
   548     if ( iQuietOn )
   573     if ( iQuietOn )
   549         {
   574         {
   550         FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() (quiet) complete") ));
   575         FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() (quiet) complete") ));
   551         return ETrue;
   576         return ETrue;
   632 
   657 
   633 // ---------------------------------------------------------------------------
   658 // ---------------------------------------------------------------------------
   634 // Manages partial AT command
   659 // Manages partial AT command
   635 // ---------------------------------------------------------------------------
   660 // ---------------------------------------------------------------------------
   636 //
   661 //
   637 TBool CDunAtCmdHandler::ManagePartialCommand( TDesC8& aCommand,
   662 TBool CDunAtCmdHandler::ManagePartialCommand()
   638                                               TBool& aNeedsCarriage )
       
   639     {
   663     {
   640     FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand()") ));
   664     FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand()") ));
   641     aNeedsCarriage = ETrue;
       
   642     // Check length of command
       
   643     if ( aCommand.Length() == 0 )
       
   644         {
       
   645         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length zero) complete") ));
       
   646         return ETrue;
       
   647         }
       
   648     // Check one character (or unit) based input data
   665     // Check one character (or unit) based input data
   649     if ( aCommand.Length() == KDunChSetMaxCharLen )
   666     if ( iInput->Length() == KDunChSetMaxCharLen )
   650         {
   667         {
   651         EchoCommand( aCommand );
   668         EchoCommand();
   652         // Handle backspace and cancel characters
   669         // Handle backspace and cancel characters
   653         TBool found = HandleSpecialCharacters( aCommand );
   670         TBool found = HandleSpecialCharacters();
   654         if ( found )
   671         if ( found )
   655             {
   672             {
   656             FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (special) complete") ));
   673             FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (special) complete") ));
   657             return ETrue;
   674             return ETrue;
   658             }
   675             }
   659         }
   676         }
   660     TBool endFound = EFalse;
   677     TBool moreNeeded = ExtractLineFromInputBuffer();
   661     TBool overflow = AppendCommandToInputBuffer( aCommand, endFound );
   678     if ( moreNeeded )
   662     if ( overflow )
   679         {
   663         {
   680         // More data is not needed with "A/" (no carriage return), check that
   664         // Overflow occurred so return ETrue (consumed) to skip all the rest
   681         // special case here, otherwise continue processing
   665         // characters until carriage return is found
   682         if ( !IsASlashCommand() )
   666         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (overflow) complete") ));
   683             {
   667         return ETrue;
   684             FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (more) complete") ));
       
   685             return ETrue;
       
   686             }
   668         }
   687         }
   669     // If something went wrong, do nothing (return consumed)
   688     // If something went wrong, do nothing (return consumed)
   670     if ( iInputBuffer.Length() <= 0 )
   689     if ( iLineBuffer.Length() <= 0 )
   671         {
   690         {
   672         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length) complete") ));
   691         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length) complete") ));
   673         return ETrue;
   692         return ETrue;
   674         }
   693         }
   675     // If "A/", no carriage return is needed, check that now
   694     // For other commands, just return with consumed
   676     if ( IsASlashCommand() )
       
   677         {
       
   678         aNeedsCarriage = EFalse;
       
   679         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (A/) complete") ));
       
   680         return EFalse;
       
   681         }
       
   682     // For other commands and if no end, just return with consumed
       
   683     if ( !endFound )
       
   684         {
       
   685         FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (void) complete") ));
       
   686         return ETrue;
       
   687         }
       
   688     FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() complete") ));
   695     FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() complete") ));
   689     return EFalse;
   696     return EFalse;
   690     }
   697     }
   691 
   698 
   692 // ---------------------------------------------------------------------------
   699 // ---------------------------------------------------------------------------
   693 // Echoes a command if echo is on
   700 // Echoes a command if echo is on
   694 // ---------------------------------------------------------------------------
   701 // ---------------------------------------------------------------------------
   695 //
   702 //
   696 TBool CDunAtCmdHandler::EchoCommand( TDesC8& aDes )
   703 TBool CDunAtCmdHandler::EchoCommand()
   697     {
   704     {
   698     FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand()") ));
   705     FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand()") ));
   699     if ( aDes.Length() > KDunChSetMaxCharLen )
   706     if ( iInput->Length() > KDunChSetMaxCharLen )
   700         {
   707         {
   701         FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (wrong length) complete") ));
   708         FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (wrong length) complete") ));
   702         return EFalse;
   709         return EFalse;
   703         }
   710         }
   704     if ( iEchoOn )
   711     if ( iEchoOn )
   705         {
   712         {
   706         iEchoBuffer.Copy( aDes );
   713         if ( iDownstream->IsDataInQueue(&iEchoBuffer) )
       
   714             {
       
   715             FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (in queue!) complete") ));
       
   716             return EFalse;
       
   717             }
       
   718         iEchoBuffer.Copy( *iInput );
   707         iDownstream->NotifyDataPushRequest( &iEchoBuffer, NULL );
   719         iDownstream->NotifyDataPushRequest( &iEchoBuffer, NULL );
   708         FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() complete") ));
   720         FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() complete") ));
   709         return ETrue;
   721         return ETrue;
   710         }
   722         }
   711     FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (not started) complete") ));
   723     FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (not started) complete") ));
   714 
   726 
   715 // ---------------------------------------------------------------------------
   727 // ---------------------------------------------------------------------------
   716 // Handles backspace and cancel characters
   728 // Handles backspace and cancel characters
   717 // ---------------------------------------------------------------------------
   729 // ---------------------------------------------------------------------------
   718 //
   730 //
   719 TBool CDunAtCmdHandler::HandleSpecialCharacters( TDesC8& aCommand )
   731 TBool CDunAtCmdHandler::HandleSpecialCharacters()
   720     {
   732     {
   721     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters()") ));
   733     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters()") ));
   722     if ( aCommand.Length() != KDunChSetMaxCharLen )
   734     if ( iInput->Length() != KDunChSetMaxCharLen )
   723         {
   735         {
   724         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (wrong length) complete") ));
   736         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (wrong length) complete") ));
   725         return EFalse;
   737         return EFalse;
   726         }
   738         }
   727     if ( aCommand[0] == iBackspace )
   739     if ( (*iInput)[0] == iBackspace )
   728         {
   740         {
   729         TInt bufferLength = iInputBuffer.Length();
   741         TInt lineLength = iLineBuffer.Length();
   730         if ( bufferLength > 0 )
   742         if ( lineLength > 0 )
   731             {
   743             {
   732             iInputBuffer.SetLength( bufferLength-1 );
   744             iLineBuffer.SetLength( lineLength-1 );
   733             }
   745             }
   734         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (backspace) complete") ));
   746         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (backspace) complete") ));
   735         return ETrue;
   747         return ETrue;
   736         }
   748         }
   737     if ( aCommand[0] == KDunCancel )
   749     if ( (*iInput)[0] == KDunCancel )
   738         {
   750         {
   739         ResetParseBuffers();  // More processing here?
   751         ManageEndOfCmdHandling( EFalse, EFalse );
   740         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (cancel) complete") ));
   752         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (cancel) complete") ));
   741         return ETrue;
   753         return ETrue;
   742         }
   754         }
   743     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() complete") ));
   755     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() complete") ));
   744     return EFalse;
   756     return EFalse;
   745     }
   757     }
   746 
   758 
   747 // ---------------------------------------------------------------------------
   759 // ---------------------------------------------------------------------------
   748 // Appends command to parse buffer
   760 // Extracts line from input buffer to line buffer
   749 // ---------------------------------------------------------------------------
   761 // ---------------------------------------------------------------------------
   750 //
   762 //
   751 TBool CDunAtCmdHandler::AppendCommandToInputBuffer( TDesC8& aCommand,
   763 TBool CDunAtCmdHandler::ExtractLineFromInputBuffer()
   752                                                     TBool& aEndFound )
   764     {
   753     {
   765     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer()") ));
   754     FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer()") ));
   766     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() before (%d bytes):"), iLineBuffer.Length() ));
   755     aEndFound = EFalse;
   767     FTRACE(FPrintRaw(iLineBuffer) );
   756     TInt cmdBufIndex = 0;
   768     // Case1: If no data in iLineBuffer and end-of-line character in iInputBuffer[start]:
   757     TInt cmdBufLim = aCommand.Length();
   769     //     - Skip end-of-line characters, find start-of-line condition, find end-of-line character
   758     while ( cmdBufIndex < cmdBufLim )
   770     //     - If partial line found (start-of-line condition and no end-of-line character):
   759         {
   771     //           - Save partial line to iLineBuffer
   760         if ( iInputBuffer.Length() == iInputBuffer.MaxLength() )
   772     //           - Set iEndIndex to end of iInputBuffer
   761             {
   773     //     - If full line found (start-of-line condition and end-of-line character):
   762             // 1) If output is full and end found from input
   774     //           - Save full line to iLineBuffer
   763             //    -> reset buffers and overflow found
   775     //           - Skip multiple end-of-line characters until next start-of-line
   764             // 2) If output is full and end not found from input
   776     //             condition or end of iInputBuffer -> save this position to iEndIndex
   765             //    -> don't reset buffers and overflow found
   777     // Case2: If no data in iLineBuffer and non-end-of-line character in iInputBuffer[start]:
   766             TInt foundIndex = FindEndOfCommand( aCommand );
   778     //     - Find end-of-line character
   767             if ( foundIndex >= 0 )
   779     //     - If partial line found (no end-of-line character):
   768                 {
   780     //           - Save partial line to iLineBuffer
   769                 aEndFound = ETrue;
   781     //           - Set iEndIndex to end of iLineBuffer
   770                 ResetParseBuffers();
   782     //     - If full line found (end-of-line character):
   771                 FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (reset) complete") ));
   783     //           - Save full line to iLineBuffer
   772                 }
   784     //           - Skip multiple end-of-line characters until next start-of-line
   773             FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (overflow) complete") ));
   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") ));
   774             return ETrue;
   846             return ETrue;
   775             }
   847             }
   776         TChar character = aCommand[cmdBufIndex];
   848         iLineBuffer.Append( &(*iInput)[startIndex], copyLength );
   777         if ( IsEndOfCommand(character) )
   849         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() after (%d bytes):"), iLineBuffer.Length() ));
   778             {
   850         FTRACE(FPrintRaw(iLineBuffer) );
   779             aEndFound = ETrue;
   851         }
   780             iEndIndex = cmdBufIndex;
   852     if ( moreNeeded )
       
   853         {
       
   854         iEndIndex = KErrNotFound;
       
   855         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (more needed) complete") ));
       
   856         return ETrue;
       
   857         }
       
   858     // As a last step adjust the possible multiple IsDelimiterCharacter()
       
   859     // characters and set length of iLineBuffer. Leave iEndIndex untouched.
       
   860     lineLength = iLineBuffer.Length();
       
   861     for ( TInt i=lineLength-1; i>=0; i-- )
       
   862         {
       
   863         TChar character = iLineBuffer[i];
       
   864         if ( !IsDelimiterCharacter(character) )
       
   865             {
       
   866             iLineBuffer.SetLength( i + 1 );
       
   867             FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() after (%d bytes):"), iLineBuffer.Length() ));
       
   868             FTRACE(FPrintRaw(iLineBuffer) );
   781             break;
   869             break;
   782             }
   870             }
   783         iInputBuffer.Append( aCommand[cmdBufIndex] );
   871         }
   784         cmdBufIndex++;
   872     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (line found) complete") ));
   785         }
       
   786     FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() complete") ));
       
   787     return EFalse;
   873     return EFalse;
   788     }
   874     }
   789 
   875 
   790 // ---------------------------------------------------------------------------
   876 // ---------------------------------------------------------------------------
   791 // Handles next decoded command from input buffer
   877 // Handles generic buffer management
   792 // ---------------------------------------------------------------------------
   878 // (explanation in ExtractLineFromInputBuffer())
   793 //
   879 // ---------------------------------------------------------------------------
   794 TBool CDunAtCmdHandler::HandleNextDecodedCommand()
   880 //
   795     {
   881 TBool CDunAtCmdHandler::HandleGenericBufferManagement( TInt& aStartIndex,
   796     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand()") ));
   882                                                        TInt& aCopyLength,
       
   883                                                        TBool& aCopyNeeded )
       
   884     {
       
   885     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement()") ));
       
   886     TInt inputLength = iInput->Length();
       
   887     TInt currentIndex = SkipEndOfLineCharacters( aStartIndex );
       
   888     if ( currentIndex >= inputLength )
       
   889         {
       
   890         // No data in iLineBuffer and only end-of-lines in new buffer
       
   891         // return with "need more data"
       
   892         iEndIndex = inputLength;
       
   893         aCopyLength = 0;
       
   894         aCopyNeeded = EFalse;
       
   895         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (new end for old no data) complete") ));
       
   896         return ETrue;
       
   897         }
       
   898     // No data in iLineBuffer and non-end-of-line character found
       
   899     // Try to find the first start-of-line condition
       
   900     TInt lineLength = iLineBuffer.Length();
       
   901     if ( lineLength == 0 )
       
   902         {
       
   903         currentIndex = SkipSubCommandDelimiterCharacters( aStartIndex );
       
   904         if ( currentIndex >= inputLength )
       
   905             {
       
   906             // No data in iLineBuffer and only end-of-lines+delimiter in new buffer
       
   907             // return with "need more data"
       
   908             iEndIndex = inputLength;
       
   909             aCopyLength = 0;
       
   910             aCopyNeeded = EFalse;
       
   911             FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (new end+delim for old no data) complete") ));
       
   912             return ETrue;
       
   913             }
       
   914         }
       
   915     aStartIndex = currentIndex;
       
   916     // No data in iLineBuffer and other than end-of-line or delimiter character found
       
   917     // Variable currentIndex is now the start of new command
       
   918     // Next try to find the end of the command
       
   919     TInt endIndex = FindEndOfLine( aStartIndex );
       
   920     if ( endIndex >= inputLength )
       
   921         {
       
   922         // No data in iLineBuffer and start of command found without end
       
   923         // return with "need more data"
       
   924         iEndIndex = inputLength;
       
   925         aCopyLength = inputLength - aStartIndex;
       
   926         aCopyNeeded = ETrue;
       
   927         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (start but no end for old no data) complete") ));
       
   928         return ETrue;
       
   929         }
       
   930     // No data in iLineBuffer and end-of-line character found
       
   931     // Try to skip possible multiple end-of-line characters
       
   932     currentIndex = SkipEndOfLineCharacters( endIndex );
       
   933     // Variable currentIndex is now either start of next command or end of iInput
       
   934     // Note that this requires that Case 2 must skip the possible IsDelimiterCharacter()s
       
   935     iEndIndex = currentIndex;
       
   936     aCopyLength = endIndex - aStartIndex;
       
   937     aCopyNeeded = ETrue;
       
   938     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (line found) complete") ));
       
   939     return EFalse;
       
   940     }
       
   941 
       
   942 // ---------------------------------------------------------------------------
       
   943 // Handles special buffer management
       
   944 // (explanation in ExtractLineFromInputBuffer())
       
   945 // ---------------------------------------------------------------------------
       
   946 //
       
   947 TBool CDunAtCmdHandler::HandleSpecialBufferManagement( TInt aStartIndex,
       
   948                                                        TInt& aCopyLength,
       
   949                                                        TBool& aCopyNeeded )
       
   950     {
       
   951     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialBufferManagement()") ));
       
   952     TInt currentIndex = SkipEndOfLineCharacters( aStartIndex );
       
   953     // Variable currentIndex is now either start of next command or end of iInput
       
   954     iEndIndex = currentIndex;
       
   955     aCopyLength = 0;
       
   956     aCopyNeeded = EFalse;
       
   957     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialBufferManagement() complete") ));
       
   958     return EFalse;
       
   959     }
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // Skips end-of-line characters
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 TInt CDunAtCmdHandler::SkipEndOfLineCharacters( TInt aStartIndex )
       
   966     {
       
   967     FTRACE(FPrint( _L("CDunAtCmdHandler::SkipEndOfLineCharacters()") ));
       
   968     TInt foundIndex = iInput->Length();
       
   969     TInt inputLength = foundIndex;
       
   970     for ( TInt i=aStartIndex; i<inputLength; i++ )
       
   971         {
       
   972         TChar character = (*iInput)[i];
       
   973         if ( !IsEndOfLine(character) )
       
   974             {
       
   975             foundIndex = i;
       
   976             break;
       
   977             }
       
   978         }
       
   979     FTRACE(FPrint( _L("CDunAtCmdHandler::SkipEndOfLineCharacters() complete") ));
       
   980     return foundIndex;
       
   981     }
       
   982 
       
   983 // ---------------------------------------------------------------------------
       
   984 // Skips subcommand delimiter characters
       
   985 // ---------------------------------------------------------------------------
       
   986 //
       
   987 TInt CDunAtCmdHandler::SkipSubCommandDelimiterCharacters( TInt aStartIndex )
       
   988     {
       
   989     FTRACE(FPrint( _L("CDunAtCmdHandler::SkipSubCommandDelimiterCharacters()") ));
       
   990     TInt inputLength = iInput->Length();
       
   991     TInt foundIndex = inputLength;
       
   992     for ( TInt i=aStartIndex; i<inputLength; i++ )
       
   993         {
       
   994         TChar character = (*iInput)[i];
       
   995         if ( !IsDelimiterCharacter(character) )
       
   996             {
       
   997             foundIndex = i;
       
   998             break;
       
   999             }
       
  1000         }
       
  1001     FTRACE(FPrint( _L("CDunAtCmdHandler::SkipSubCommandDelimiterCharacters() complete") ));
       
  1002     return foundIndex;
       
  1003     }
       
  1004 
       
  1005 // ---------------------------------------------------------------------------
       
  1006 // Finds the end of the line
       
  1007 // ---------------------------------------------------------------------------
       
  1008 //
       
  1009 TInt CDunAtCmdHandler::FindEndOfLine( TInt aStartIndex )
       
  1010     {
       
  1011     FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfLine()") ));
       
  1012     TInt inputLength = iInput->Length();
       
  1013     TInt foundIndex = inputLength;
       
  1014     for ( TInt i=aStartIndex; i<inputLength; i++ )
       
  1015         {
       
  1016         TChar character = (*iInput)[i];
       
  1017         // Checking for IsDelimiterCharacter() here needs more logic (a parser).
       
  1018         // Just check with "IsEndOfLine()"
       
  1019         if ( IsEndOfLine(character) )
       
  1020             {
       
  1021             foundIndex = i;
       
  1022             break;
       
  1023             }
       
  1024         }
       
  1025     FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfLine() complete") ));
       
  1026     return foundIndex;
       
  1027     }
       
  1028 
       
  1029 // ---------------------------------------------------------------------------
       
  1030 // Handles next subcommand from line buffer
       
  1031 // ---------------------------------------------------------------------------
       
  1032 //
       
  1033 TBool CDunAtCmdHandler::HandleNextSubCommand()
       
  1034     {
       
  1035     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextSubCommand()") ));
   797     if ( iHandleState != EDunStateAtCmdHandling )
  1036     if ( iHandleState != EDunStateAtCmdHandling )
   798         {
  1037         {
   799         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (not ready) complete") ));
  1038         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextSubCommand() (not ready) complete") ));
   800         return ETrue;
  1039         return EFalse;
   801         }
  1040         }
   802     TBool extracted = ExtractNextDecodedCommand();
  1041     TBool extracted = ExtractNextSubCommand();
   803     if ( !extracted )
  1042     if ( !extracted )
   804         {
  1043         {
   805         ManageEndOfCmdHandling( ETrue, ETrue, ETrue );
  1044         ManageEndOfCmdHandling( ETrue, ETrue );
   806         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (last) complete") ));
  1045         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextSubCommand() (last) complete") ));
   807         return ETrue;
  1046         return EFalse;
   808         }
  1047         }
   809     // Next convert the decoded AT command to uppercase
  1048     // Next convert the decoded AT command to uppercase
   810     // Don't check for case status -> let mixed cases pass
  1049     // Don't check for case status -> let mixed cases pass
   811     iParseInfo.iSendBuffer.Copy( iDecodeInfo.iDecodeBuffer );
  1050     TInt oldLength = iParseInfo.iSendBuffer.Length();
   812     TInt maxLength = iParseInfo.iSendBuffer.MaxLength();
  1051     iParseInfo.iSendBuffer.SetLength( iParseInfo.iLimit );
   813     TPtr8 upperDes( &iParseInfo.iSendBuffer[0], iParseInfo.iLimit, maxLength );
  1052     iParseInfo.iSendBuffer.UpperCase();
   814     upperDes.UpperCase();
  1053     iParseInfo.iSendBuffer.SetLength( oldLength );
   815     // Next always send the command to ATEXT
  1054     // Next always send the command to ATEXT
   816     iCmdPusher->IssueRequest( iParseInfo.iSendBuffer );
  1055     iCmdPusher->IssueRequest( iParseInfo.iSendBuffer );
   817     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") ));
  1056     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextSubCommand() complete") ));
   818     return EFalse;
  1057     return ETrue;
   819     }
       
   820 
       
   821 // ---------------------------------------------------------------------------
       
   822 // Finds the start of the next command
       
   823 // ---------------------------------------------------------------------------
       
   824 //
       
   825 TInt CDunAtCmdHandler::FindStartOfNextCommand()
       
   826     {
       
   827     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand()") ));
       
   828     // Note: here we need to avoid internal recursion when parsing the
       
   829     // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the
       
   830     // same upstream block.
       
   831     // Skip all the extra markers except the one we already know to exist.
       
   832     TInt i;
       
   833     TInt startVal = iEndIndex + 1;
       
   834     TInt foundIndex = KErrNotFound;
       
   835     TInt count = iCommand->Length();
       
   836     for ( i=startVal; i<count; i++ )
       
   837         {
       
   838         TChar character = (*iCommand)[i];
       
   839         if ( !(IsEndOfCommand(character)||IsDelimiterCharacter(character)) )
       
   840             {
       
   841             foundIndex = i;
       
   842             break;
       
   843             }
       
   844         }
       
   845     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand() complete") ));
       
   846     return foundIndex;
       
   847     }
  1058     }
   848 
  1059 
   849 // ---------------------------------------------------------------------------
  1060 // ---------------------------------------------------------------------------
   850 // Manages end of AT command handling
  1061 // Manages end of AT command handling
   851 // ---------------------------------------------------------------------------
  1062 // ---------------------------------------------------------------------------
   852 //
  1063 //
   853 void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal,
  1064 void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyLocal,
   854                                                TBool aNotifyLocal,
  1065                                                TBool aNotifyExternal )
   855                                                TBool aClearInput )
       
   856     {
  1066     {
   857     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") ));
  1067     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") ));
   858     if ( iInputBuffer.Length() > 0 )
  1068     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (loc=%d, ext=%d)"), aNotifyLocal, aNotifyExternal ));
   859         {
  1069     // If iEndIndex is (>=0 && <iInput.Length()) it means more data waits in
   860         iLastBuffer.Copy( iInputBuffer );
  1070     // iInput that didn't fit in iInputBuffer.
   861         }
  1071     TInt cmdLength = iInput->Length();
   862     ResetParseBuffers( aClearInput );
  1072     TBool subBlock = ( iEndIndex>=0&&iEndIndex<cmdLength ) ? ETrue : EFalse;
       
  1073     if ( iLineBuffer.Length()>0 && !subBlock )
       
  1074         {
       
  1075         // Line buffer set and no partial subblock, copy to lastbuffer
       
  1076         iLastBuffer.Copy( iLineBuffer );
       
  1077         }
       
  1078     iLineBuffer.Zero();
       
  1079     iDecodeInfo.iFirstDecode = ETrue;
       
  1080     iDecodeInfo.iDecodeIndex = 0;
       
  1081     iDecodeInfo.iPrevExists = EFalse;
       
  1082     iParseInfo.iLimit = KErrNotFound;
       
  1083     iParseInfo.iSendBuffer.Zero();
       
  1084     iEditorModeInfo.iContentFound = EFalse;
   863     iHandleState = EDunStateIdle;
  1085     iHandleState = EDunStateIdle;
   864     if ( aNotifyLocal )
  1086     if ( aNotifyLocal )
   865         {
  1087         {
   866         iCmdPusher->SetEndOfCmdLine();
  1088         iCmdPusher->SetEndOfCmdLine();
   867         }
  1089         }
   868     if ( !aNotifyExternal )
  1090     // iEndIndex must not be reset to KErrNotFound only when
   869         {
  1091     // ExtractLineFromInputBuffer() found the next line
   870         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") ));
  1092     // (when moreNeeded is EFalse)
   871         return;
  1093     TBool resetIndex = ETrue;
   872         }
  1094     if ( aNotifyExternal )
   873     TInt foundIndex = FindStartOfNextCommand();
  1095         {
   874     iUpstream->NotifyAtCmdHandlingEnd( foundIndex );
  1096         TBool moreNeeded = ExtractLineFromInputBuffer();
       
  1097         if ( moreNeeded )
       
  1098             {
       
  1099             iUpstream->NotifyParserNeedsMoreData();
       
  1100             }
       
  1101         else
       
  1102             {
       
  1103             // AppendBlockToInputBuffer() was able to fill with known end, handle next
       
  1104             iHandleState = EDunStateAtCmdHandling;
       
  1105             HandleNextSubCommand();
       
  1106             resetIndex = EFalse;
       
  1107             }
       
  1108         }
       
  1109     if ( resetIndex )
       
  1110         {
       
  1111         iEndIndex = KErrNotFound;
       
  1112         }
   875     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") ));
  1113     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") ));
   876     }
  1114     }
   877 
  1115 
   878 // ---------------------------------------------------------------------------
  1116 // ---------------------------------------------------------------------------
   879 // Extracts next decoded command from input buffer to decode buffer
  1117 // Extracts next subcommand from line buffer to send buffer
   880 // ---------------------------------------------------------------------------
  1118 // ---------------------------------------------------------------------------
   881 //
  1119 //
   882 TBool CDunAtCmdHandler::ExtractNextDecodedCommand( TBool aPeek )
  1120 TBool CDunAtCmdHandler::ExtractNextSubCommand( TBool aPeek )
   883     {
  1121     {
   884     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") ));
  1122     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand()") ));
       
  1123     TDunDecodeInfo oldInfo = iDecodeInfo;
   885     iParseInfo.iLimit = KErrNotFound;
  1124     iParseInfo.iLimit = KErrNotFound;
   886     TDunDecodeInfo oldInfo = iDecodeInfo;
  1125     iParseInfo.iSendBuffer.Zero();
   887     iDecodeInfo.iDecodeBuffer.Zero();
  1126     // Find start of subcommand from line buffer
   888     // Find start of decode command from input buffer
  1127     TInt startIndex = FindStartOfSubCommand();
   889     TInt startIndex = iDecodeInfo.iDecodeIndex;
       
   890     startIndex = FindStartOfDecodedCommand( iInputBuffer, startIndex );
       
   891     if ( startIndex < 0 )
  1128     if ( startIndex < 0 )
   892         {
  1129         {
   893         RestoreOldDecodeInfo( aPeek, oldInfo );
  1130         RestoreOldDecodeInfo( aPeek, oldInfo );
   894         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") ));
  1131         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") ));
   895         return EFalse;
  1132         return EFalse;
   896         }
  1133         }
   897     // Find end of decode command from input buffer
  1134     iDecodeInfo.iDecodeIndex = startIndex;
   898     TBool specialCmd = EFalse;
  1135     TBool specialCmd = EFalse;
   899     TInt endIndex = KErrNotFound;
  1136     TInt endIndex = KErrNotFound;
   900     specialCmd = CheckSpecialCommand( startIndex, endIndex );
  1137     specialCmd = CheckSpecialCommand( endIndex );
   901     if ( !specialCmd )
  1138     if ( !specialCmd )
   902         {
  1139         {
   903         FindSubCommand( startIndex, endIndex );
  1140         FindSubCommand( endIndex );
   904         }
  1141         }
   905     if ( endIndex < startIndex )
  1142     TInt lineLength = iLineBuffer.Length();
       
  1143     TBool inStartLimits = ( startIndex >= 0 && startIndex < lineLength ) ? ETrue : EFalse;
       
  1144     TBool inEndLimits   = ( endIndex   >= 0 && endIndex   < lineLength ) ? ETrue : EFalse;
       
  1145     if ( !inStartLimits || !inEndLimits )
   906         {
  1146         {
   907         RestoreOldDecodeInfo( aPeek, oldInfo );
  1147         RestoreOldDecodeInfo( aPeek, oldInfo );
   908         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") ));
  1148         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand() (no end) complete") ));
   909         return EFalse;
  1149         return EFalse;
   910         }
  1150         }
   911     TInt cmdLength = endIndex - startIndex + 1;
  1151     TInt cmdLength = endIndex - startIndex + 1;
   912     // If the limit was not already set then do it now
  1152     // If the limit was not already set then do it now
   913     if ( iParseInfo.iLimit < 0 )
  1153     if ( iParseInfo.iLimit < 0 )
   914         {
  1154         {
   915         iParseInfo.iLimit = cmdLength;
  1155         iParseInfo.iLimit = cmdLength;
   916         }
  1156         }
   917     // Next create a new command
  1157     // Next create a new command
   918     if ( !iDecodeInfo.iFirstDecode && !specialCmd )
  1158     if ( !iDecodeInfo.iFirstDecode )
   919         {
  1159         {
   920         _LIT( KAtMsg, "AT" );
  1160         _LIT( KAtPrefix, "AT" );
   921         iDecodeInfo.iDecodeBuffer.Append( KAtMsg );
  1161         iParseInfo.iSendBuffer.Append( KAtPrefix );
   922         iParseInfo.iLimit += 2;  // Length of "AT"
  1162         if ( !specialCmd )  // Already added with CheckSpecialCommand()
       
  1163             {
       
  1164             iParseInfo.iLimit += 2;  // Length of "AT"
       
  1165             }
   923         // Note: The length of iDecodeBuffer is not exceeded here because "AT"
  1166         // Note: The length of iDecodeBuffer is not exceeded here because "AT"
   924         // is added only for the second commands after that.
  1167         // is added only for the second commands after that.
   925         }
  1168         }
   926     TPtrC8 decodedCmd = iInputBuffer.Mid( startIndex, cmdLength );
  1169     iParseInfo.iSendBuffer.Append( &iLineBuffer[startIndex], cmdLength );
   927     iDecodeInfo.iDecodeBuffer.Append( decodedCmd );
  1170     // Change settings for the next decode round
   928     // Set index for next round
       
   929     iDecodeInfo.iFirstDecode = EFalse;
  1171     iDecodeInfo.iFirstDecode = EFalse;
   930     iDecodeInfo.iDecodeIndex = endIndex + 1;
  1172     iDecodeInfo.iDecodeIndex = endIndex + 1;
   931     RestoreOldDecodeInfo( aPeek, oldInfo );
  1173     RestoreOldDecodeInfo( aPeek, oldInfo );
   932     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() complete") ));
  1174     if ( !aPeek )
       
  1175         {
       
  1176         iDecodeInfo.iCmdsHandled++;
       
  1177         FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand() (handled=%d)"), iDecodeInfo.iCmdsHandled ));
       
  1178         }
       
  1179     FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand() complete") ));
   933     return ETrue;
  1180     return ETrue;
       
  1181     }
       
  1182 
       
  1183 // ---------------------------------------------------------------------------
       
  1184 // Finds the start of subcommand from line buffer
       
  1185 // ---------------------------------------------------------------------------
       
  1186 //
       
  1187 TBool CDunAtCmdHandler::FindStartOfSubCommand()
       
  1188     {
       
  1189     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfSubCommand()") ));
       
  1190     TInt i;
       
  1191     TInt foundIndex = KErrNotFound;
       
  1192     TInt lineLength = iLineBuffer.Length();
       
  1193     for ( i=iDecodeInfo.iDecodeIndex; i<lineLength; i++ )
       
  1194         {
       
  1195         TChar character = iLineBuffer[i];
       
  1196         if ( !IsDelimiterCharacter(character) )
       
  1197             {
       
  1198             foundIndex = i;
       
  1199             break;
       
  1200             }
       
  1201         }
       
  1202     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfSubCommand() complete") ));
       
  1203     return foundIndex;
   934     }
  1204     }
   935 
  1205 
   936 // ---------------------------------------------------------------------------
  1206 // ---------------------------------------------------------------------------
   937 // Restores old decode info. For ExtractNextDecodedCommand() when aPeeks is
  1207 // Restores old decode info. For ExtractNextDecodedCommand() when aPeeks is
   938 // ETrue.
  1208 // ETrue.
   949         }
  1219         }
   950     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") ));
  1220     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") ));
   951     }
  1221     }
   952 
  1222 
   953 // ---------------------------------------------------------------------------
  1223 // ---------------------------------------------------------------------------
   954 // Finds end of an AT command
  1224 // Tests for end of AT command line
   955 // ---------------------------------------------------------------------------
  1225 // ---------------------------------------------------------------------------
   956 //
  1226 //
   957 TInt CDunAtCmdHandler::FindEndOfCommand( TDesC8& aDes, TInt aStartIndex )
  1227 TBool CDunAtCmdHandler::IsEndOfLine( TChar& aCharacter )
   958     {
       
   959     FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand()") ));
       
   960     TInt i;
       
   961     TInt length = aDes.Length();
       
   962     for ( i=aStartIndex; i<length; i++ )
       
   963         {
       
   964         TChar character = aDes[i];
       
   965         if ( IsEndOfCommand(character) )
       
   966             {
       
   967             FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand() complete (%d)"), i ));
       
   968             return i;
       
   969             }
       
   970         }
       
   971     FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand() (not found) complete") ));
       
   972     return KErrNotFound;
       
   973     }
       
   974 
       
   975 // ---------------------------------------------------------------------------
       
   976 // Tests for end of AT command character
       
   977 // ---------------------------------------------------------------------------
       
   978 //
       
   979 TBool CDunAtCmdHandler::IsEndOfCommand( TChar& aCharacter )
       
   980     {
  1228     {
   981     FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand()") ));
  1229     FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand()") ));
   982     if ( aCharacter==iCarriageReturn || aCharacter==iLineFeed )
  1230     if ( aCharacter==iCarriageReturn || aCharacter==iLineFeed )
   983         {
  1231         {
   984         FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (found) complete") ));
  1232         FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (found) complete") ));
   985         return ETrue;
  1233         return ETrue;
   986         }
  1234         }
   987     FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (not found) complete") ));
  1235     FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (not found) complete") ));
   988     return EFalse;
  1236     return EFalse;
   989     }
       
   990 
       
   991 // ---------------------------------------------------------------------------
       
   992 // Finds start of a decoded AT command
       
   993 // ---------------------------------------------------------------------------
       
   994 //
       
   995 TInt CDunAtCmdHandler::FindStartOfDecodedCommand( TDesC8& aDes,
       
   996                                                   TInt aStartIndex )
       
   997     {
       
   998     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand()") ));
       
   999     TInt i;
       
  1000     TInt count = aDes.Length();
       
  1001     for ( i=aStartIndex; i<count; i++ )
       
  1002         {
       
  1003         TChar character = aDes[i];
       
  1004         if ( !IsDelimiterCharacter(character) )
       
  1005             {
       
  1006             FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand() complete (%d)"), i ));
       
  1007             return i;
       
  1008             }
       
  1009         }
       
  1010     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand() (not found) complete") ));
       
  1011     return KErrNotFound;
       
  1012     }
  1237     }
  1013 
  1238 
  1014 // ---------------------------------------------------------------------------
  1239 // ---------------------------------------------------------------------------
  1015 // Checks if character is delimiter character
  1240 // Checks if character is delimiter character
  1016 // ---------------------------------------------------------------------------
  1241 // ---------------------------------------------------------------------------
  1047 
  1272 
  1048 // ---------------------------------------------------------------------------
  1273 // ---------------------------------------------------------------------------
  1049 // Checks special command
  1274 // Checks special command
  1050 // ---------------------------------------------------------------------------
  1275 // ---------------------------------------------------------------------------
  1051 //
  1276 //
  1052 TBool CDunAtCmdHandler::CheckSpecialCommand( TInt aStartIndex,
  1277 TBool CDunAtCmdHandler::CheckSpecialCommand( TInt& aEndIndex )
  1053                                              TInt& aEndIndex )
       
  1054     {
  1278     {
  1055     FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand()") ));
  1279     FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand()") ));
  1056     TBuf8<KDunInputBufLength> upperBuf;
  1280     TInt atPrefixLen = 0;
  1057     TInt newLength = iInputBuffer.Length() - aStartIndex;
  1281     TInt startIndex = iDecodeInfo.iDecodeIndex;
  1058     upperBuf.Copy( &iInputBuffer[aStartIndex], newLength );
  1282     TInt newLength = iLineBuffer.Length() - startIndex;
       
  1283     TBuf8<KDunLineBufLength> upperBuf;
       
  1284     if ( !iDecodeInfo.iFirstDecode )
       
  1285         {
       
  1286         // For cases such as "ATM1L3DT*99#" "DT" must have "AT"
       
  1287         _LIT8( KAtPrefix, "AT" );
       
  1288         upperBuf.Copy( KAtPrefix );
       
  1289         atPrefixLen = 2;  // "AT"
       
  1290         newLength += atPrefixLen;
       
  1291         }
       
  1292     upperBuf.Append( &iLineBuffer[startIndex], newLength );
  1059     upperBuf.UpperCase();
  1293     upperBuf.UpperCase();
  1060     TInt i;
  1294     TInt i;
  1061     TInt count = iSpecials.Count();
  1295     TInt count = iSpecials.Count();
  1062     for ( i=0; i<count; i++ )
  1296     for ( i=0; i<count; i++ )
  1063         {
  1297         {
  1075         TInt cmpResult = upperBuf.Compare( *specialCmd );
  1309         TInt cmpResult = upperBuf.Compare( *specialCmd );
  1076         upperBuf.SetLength( origLength );
  1310         upperBuf.SetLength( origLength );
  1077         if ( cmpResult == 0 )
  1311         if ( cmpResult == 0 )
  1078             {
  1312             {
  1079             iParseInfo.iLimit = specialLength;
  1313             iParseInfo.iLimit = specialLength;
  1080             aEndIndex = (origLength-1) + aStartIndex;
  1314             aEndIndex = (origLength-1) + startIndex - atPrefixLen;
  1081             FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() complete") ));
  1315             FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() complete") ));
  1082             return ETrue;
  1316             return ETrue;
  1083             }
  1317             }
  1084         }
  1318         }
  1085     FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() (not found) complete") ));
  1319     FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() (not found) complete") ));
  1253 
  1487 
  1254 // ---------------------------------------------------------------------------
  1488 // ---------------------------------------------------------------------------
  1255 // Finds subcommand
  1489 // Finds subcommand
  1256 // ---------------------------------------------------------------------------
  1490 // ---------------------------------------------------------------------------
  1257 //
  1491 //
  1258 TInt CDunAtCmdHandler::FindSubCommand( TInt aStartIndex, TInt& aEndIndex )
  1492 TInt CDunAtCmdHandler::FindSubCommand( TInt& aEndIndex )
  1259     {
  1493     {
  1260     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand()") ));
  1494     FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand()") ));
  1261     aEndIndex = aStartIndex;
  1495     TInt startIndex = iDecodeInfo.iDecodeIndex;
       
  1496     aEndIndex = startIndex;
  1262     TBool found = EFalse;
  1497     TBool found = EFalse;
  1263     TInt length = iInputBuffer.Length();
  1498     TInt lineLength = iLineBuffer.Length();
  1264     iDecodeInfo.iAssignFound = EFalse;
  1499     iDecodeInfo.iAssignFound = EFalse;
  1265     iDecodeInfo.iInQuotes = EFalse;
  1500     iDecodeInfo.iInQuotes = EFalse;
  1266     iDecodeInfo.iExtendedIndex = KErrNotFound;
  1501     iDecodeInfo.iExtendedIndex = KErrNotFound;
  1267     SaveNotFoundCharDecodeState();
  1502     SaveNotFoundCharDecodeState();
  1268     iAtSpecialCmdHandler->ResetComparisonBuffer();  // just to be sure
  1503     iAtSpecialCmdHandler->ResetComparisonBuffer();  // just to be sure
  1269     for ( ; aEndIndex<length; aEndIndex++ )
  1504     for ( ; aEndIndex<lineLength; aEndIndex++ )
  1270         {
  1505         {
  1271         TChar character = iInputBuffer[aEndIndex];
  1506         TChar character = iLineBuffer[aEndIndex];
  1272         found = FindSubCommandQuotes( character, aStartIndex, aEndIndex );
  1507         found = FindSubCommandQuotes( character, startIndex, aEndIndex );
  1273         if ( found )
  1508         if ( found )
  1274             {
  1509             {
  1275             continue;
  1510             continue;
  1276             }
  1511             }
  1277         if ( character == '?' )
  1512         if ( character == '?' )
  1290         // The check below detects the following type of cases:
  1525         // The check below detects the following type of cases:
  1291         // ATCMD+CMD [first + as delimiter]
  1526         // ATCMD+CMD [first + as delimiter]
  1292         // AT+CMD+CMD [second + as delimiter]
  1527         // AT+CMD+CMD [second + as delimiter]
  1293         if ( IsExtendedCharacter(character) )
  1528         if ( IsExtendedCharacter(character) )
  1294             {
  1529             {
  1295             found = IsExtendedBorder( character, aStartIndex, aEndIndex );
  1530             found = IsExtendedBorder( character, startIndex, aEndIndex );
  1296             if ( !found )
  1531             if ( !found )
  1297                 {
  1532                 {
  1298                 continue;
  1533                 continue;
  1299                 }
  1534                 }
  1300             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (extended) complete") ));
  1535             FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (extended) complete") ));
  1318 // ---------------------------------------------------------------------------
  1553 // ---------------------------------------------------------------------------
  1319 //
  1554 //
  1320 TBool CDunAtCmdHandler::IsASlashCommand()
  1555 TBool CDunAtCmdHandler::IsASlashCommand()
  1321     {
  1556     {
  1322     FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand()") ));
  1557     FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand()") ));
  1323     if ( iInputBuffer.Length() == 2 )
  1558     if ( iLineBuffer.Length() == 2 )
  1324         {
  1559         {
  1325         if ( iInputBuffer[1] == '/' &&
  1560         if ( iLineBuffer[1] == '/' &&
  1326             (iInputBuffer[0] == 'A' || iInputBuffer[0] == 'a') )
  1561             (iLineBuffer[0] == 'A' || iLineBuffer[0] == 'a') )
  1327             {
  1562             {
  1328             FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (found) complete") ));
  1563             FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (found) complete") ));
  1329             return ETrue;
  1564             return ETrue;
  1330             }
  1565             }
  1331         }
  1566         }
  1344     if ( !IsASlashCommand() )
  1579     if ( !IsASlashCommand() )
  1345         {
  1580         {
  1346         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (no push) complete") ));
  1581         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (no push) complete") ));
  1347         return EFalse;
  1582         return EFalse;
  1348         }
  1583         }
       
  1584     iEndIndex = iInput->Length();  // Causes skipping of last '/' in ManageEndOfCmdHandling()
  1349     // If "A/" command and last buffer exist, set the last buffer as the current buffer
  1585     // If "A/" command and last buffer exist, set the last buffer as the current buffer
  1350     if ( iLastBuffer.Length() > 0 )
  1586     if ( iLastBuffer.Length() > 0 )
  1351         {
  1587         {
  1352         iInputBuffer.Copy( iLastBuffer );
  1588         iLineBuffer.Copy( iLastBuffer );
  1353         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (copy) complete") ));
  1589         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (copy) complete") ));
  1354         return EFalse;
  1590         return EFalse;
  1355         }
  1591         }
  1356     // Last buffer not set so return "ERROR" if quiet mode not on
  1592     // Last buffer not set so return "ERROR"
  1357     if ( iQuietOn )
       
  1358         {
       
  1359         FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (quiet) complete") ));
       
  1360         return EFalse;
       
  1361         }
       
  1362     iDownstream->NotifyDataPushRequest( &iErrorBuffer, NULL );
  1593     iDownstream->NotifyDataPushRequest( &iErrorBuffer, NULL );
  1363     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() complete") ));
  1594     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() complete") ));
  1364     return ETrue;
  1595     return ETrue;
  1365     }
       
  1366 
       
  1367 // ---------------------------------------------------------------------------
       
  1368 // Resets parse buffers
       
  1369 // ---------------------------------------------------------------------------
       
  1370 //
       
  1371 void CDunAtCmdHandler::ResetParseBuffers( TBool aClearInput )
       
  1372     {
       
  1373     FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers()") ));
       
  1374     if ( aClearInput )
       
  1375         {
       
  1376         iInputBuffer.Zero();
       
  1377         }
       
  1378     iDecodeInfo.iFirstDecode = ETrue;
       
  1379     iDecodeInfo.iDecodeIndex = 0;
       
  1380     iDecodeInfo.iPrevExists = EFalse;
       
  1381     iDecodeInfo.iDecodeBuffer.Zero();
       
  1382     FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers() complete") ));
       
  1383     }
  1596     }
  1384 
  1597 
  1385 // ---------------------------------------------------------------------------
  1598 // ---------------------------------------------------------------------------
  1386 // Manages command mode change
  1599 // Manages command mode change
  1387 // ---------------------------------------------------------------------------
  1600 // ---------------------------------------------------------------------------
  1571     // When end of input notify CDunUpstream to reissue the read request.
  1784     // When end of input notify CDunUpstream to reissue the read request.
  1572     TBool nextContentFound = FindNextContent( aStart );
  1785     TBool nextContentFound = FindNextContent( aStart );
  1573     if ( !nextContentFound )
  1786     if ( !nextContentFound )
  1574         {
  1787         {
  1575         iUpstream->NotifyEditorModeReply( aStart );
  1788         iUpstream->NotifyEditorModeReply( aStart );
  1576         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") ));
  1789         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply() complete") ));
  1577         return KErrNone;
  1790         return KErrNone;
  1578         }
  1791         }
  1579     // In block mode end the block mode by sending <ESC> and hope it works.
  1792     // In block mode end the block mode by sending <ESC> and hope it works.
  1580     iEscapeBuffer.Zero();
  1793     iEscapeBuffer.Zero();
  1581     iEscapeBuffer.Append( KDunEscape );
  1794     iEscapeBuffer.Append( KDunEscape );
  1594     if ( !aStart )
  1807     if ( !aStart )
  1595         {
  1808         {
  1596         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (skip) complete" ) ));
  1809         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (skip) complete" ) ));
  1597         return iEditorModeInfo.iContentFound;
  1810         return iEditorModeInfo.iContentFound;
  1598         }
  1811         }
  1599     iEditorModeInfo.iContentFound = EFalse;
  1812     // If iEndIndex is (>=0 && <iInput.Length()) it means more data waits in
  1600     TInt foundCmdIndex = KErrNotFound;
  1813     // iInput that didn't fit in iInputBuffer. Only check FindStartOfCommand()
  1601     TBool nextContentFound = ExtractNextDecodedCommand( ETrue );  // peek
  1814     // if iEndIndex < 0, meaning more data is needed from CDunUpstream.
  1602     if ( !nextContentFound )
  1815     TBool contentFound = EFalse;
  1603         {
  1816     TInt cmdLength = iInput->Length();
  1604         // Check the next subblock
  1817     TBool subBlock = ( iEndIndex>=0&&iEndIndex<cmdLength ) ? ETrue : EFalse;
  1605         foundCmdIndex = FindStartOfNextCommand();
  1818     if ( subBlock )
  1606         }
  1819         {
  1607     if ( !nextContentFound && foundCmdIndex<0 )
  1820         contentFound = ETrue;
  1608         {
  1821         }
  1609         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (not found) complete") ));
  1822     if ( !contentFound )
  1610         return EFalse;
  1823         {
  1611         }
  1824         contentFound = ExtractNextSubCommand( ETrue );  // peek
  1612     iEditorModeInfo.iContentFound = ETrue;
  1825         }
       
  1826     iEditorModeInfo.iContentFound = contentFound;
  1613     FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() complete" ) ));
  1827     FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() complete" ) ));
  1614     return ETrue;
  1828     return contentFound;
  1615     }
  1829     }
  1616 
  1830 
  1617 // ---------------------------------------------------------------------------
  1831 // ---------------------------------------------------------------------------
  1618 // From class MDunAtCmdPusher.
  1832 // From class MDunAtCmdPusher.
  1619 // Notifies about end of AT command processing. This is after all reply data
  1833 // Notifies about end of AT command processing. This is after all reply data
  1628         {
  1842         {
  1629         ManageEditorModeReply( ETrue );
  1843         ManageEditorModeReply( ETrue );
  1630         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() (editor) complete" ) ));
  1844         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() (editor) complete" ) ));
  1631         return KErrNone;
  1845         return KErrNone;
  1632         }
  1846         }
  1633     HandleNextDecodedCommand();
  1847     HandleNextSubCommand();
  1634     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) ));
  1848     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) ));
  1635     return KErrNone;
  1849     return KErrNone;
  1636     }
  1850     }
  1637 
  1851 
  1638 // ---------------------------------------------------------------------------
  1852 // ---------------------------------------------------------------------------
  1639 // From class MDunAtCmdPusher.
  1853 // From class MDunAtCmdPusher.
  1640 // Notifies about request to stop AT command handling for the rest of the
  1854 // Notifies about request to stop AT command handling for the rest of the
  1641 // command line data
  1855 // command line data
  1642 // ---------------------------------------------------------------------------
  1856 // ---------------------------------------------------------------------------
  1643 //
  1857 //
  1644 TInt CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()
  1858 void CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()
  1645     {
  1859     {
  1646     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()" ) ));
  1860     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()" ) ));
  1647     TInt retVal = Stop();
  1861     ManageEndOfCmdHandling( ETrue, ETrue );
  1648     ManageEndOfCmdHandling( ETrue, EFalse, ETrue );
       
  1649     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() complete" ) ));
  1862     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() complete" ) ));
  1650     return retVal;
       
  1651     }
  1863     }
  1652 
  1864 
  1653 // ---------------------------------------------------------------------------
  1865 // ---------------------------------------------------------------------------
  1654 // From class MDunAtCmdPusher.
  1866 // From class MDunAtCmdPusher.
  1655 // Notifies about request to peek for the next command
  1867 // Notifies about request to peek for the next command
  1656 // ---------------------------------------------------------------------------
  1868 // ---------------------------------------------------------------------------
  1657 //
  1869 //
  1658 TBool CDunAtCmdHandler::NotifyNextCommandPeekRequest()
  1870 TBool CDunAtCmdHandler::NotifyNextCommandPeekRequest()
  1659     {
  1871     {
  1660     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") ));
  1872     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") ));
  1661     TBool extracted = ExtractNextDecodedCommand( ETrue );
  1873     TBool extracted = ExtractNextSubCommand( ETrue );
  1662     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") ));
  1874     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") ));
  1663     return extracted;
  1875     return extracted;
  1664     }
  1876     }
  1665 
  1877 
  1666 // ---------------------------------------------------------------------------
  1878 // ---------------------------------------------------------------------------