localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp
changeset 32 51f207bebb06
parent 31 3b92f7acdc91
child 20 2553637c2525
equal deleted inserted replaced
31:3b92f7acdc91 32:51f207bebb06
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    33 #include "DunAtCmdHandler.h"
    33 #include "DunAtCmdHandler.h"
    34 #include "DunAtUrcHandler.h"
    34 #include "DunAtUrcHandler.h"
    35 #include "DunDownstream.h"
    35 #include "DunDownstream.h"
    36 #include "DunDebug.h"
    36 #include "DunDebug.h"
    37 
    37 
    38 const TInt8 KDunCancel = 24;
    38 const TInt8 KDunCancel = 24;  // Used for line editing, cancel character
       
    39 const TInt8 KDunEscape = 27;  // Used for editor ending, escape character
    39 
    40 
    40 // ---------------------------------------------------------------------------
    41 // ---------------------------------------------------------------------------
    41 // Two-phased constructor.
    42 // Two-phased constructor.
    42 // ---------------------------------------------------------------------------
    43 // ---------------------------------------------------------------------------
    43 //
    44 //
    77     // APIs affecting this:
    78     // APIs affecting this:
    78     // IssueRequest()
    79     // IssueRequest()
    79     Stop();
    80     Stop();
    80     // NewL()
    81     // NewL()
    81     DeletePluginHandlers();
    82     DeletePluginHandlers();
       
    83     delete iCmdEchoer;
       
    84     iCmdEchoer = NULL;
    82     delete iNvramListen;
    85     delete iNvramListen;
    83     iNvramListen = NULL;
    86     iNvramListen = NULL;
    84     delete iModeListen;
    87     delete iModeListen;
    85     iModeListen = NULL;
    88     iModeListen = NULL;
    86     delete iEcomListen;
    89     delete iEcomListen;
   143                                               TBool& aPartialInput )
   146                                               TBool& aPartialInput )
   144     {
   147     {
   145     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") ));
   148     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") ));
   146     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") ));
   149     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") ));
   147     FTRACE(FPrintRaw(aCommand) );
   150     FTRACE(FPrintRaw(aCommand) );
   148     iCommand = &aCommand;
   151     TBool editorMode = iCmdPusher->EditorMode();
       
   152     if ( editorMode )
       
   153         {
       
   154         // Note: return here with "no partial input" and some error to fool
       
   155         // CDunUpstream into not reissuing the read request.
       
   156         iCmdPusher->IssueRequest( aCommand, EFalse );
       
   157         aPartialInput = EFalse;
       
   158         return KErrGeneral;
       
   159         }
       
   160     iCommand = &aCommand;  // iCommand only for normal mode
   149     // Manage partial AT command
   161     // Manage partial AT command
   150     TBool needsCarriage = ETrue;
   162     TBool needsCarriage = ETrue;
   151     TBool okToExit = ManagePartialCommand( aCommand, needsCarriage );
   163     TBool okToExit = ManagePartialCommand( aCommand, needsCarriage );
   152     if ( okToExit )
   164     if ( okToExit )
   153         {
   165         {
   178     iHandleState = EDunStateAtCmdHandling;
   190     iHandleState = EDunStateAtCmdHandling;
   179     iUpstream->NotifyAtCmdHandlingStart();
   191     iUpstream->NotifyAtCmdHandlingStart();
   180     iDecodeInfo.iFirstDecode = ETrue;
   192     iDecodeInfo.iFirstDecode = ETrue;
   181     iDecodeInfo.iDecodeIndex = 0;
   193     iDecodeInfo.iDecodeIndex = 0;
   182     HandleNextDecodedCommand();
   194     HandleNextDecodedCommand();
   183     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not supported) complete") ));
   195     FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() complete") ));
   184     aPartialInput = EFalse;
   196     aPartialInput = EFalse;
   185     return KErrNone;
   197     return KErrNone;
   186     }
   198     }
   187 
   199 
   188 // ---------------------------------------------------------------------------
   200 // ---------------------------------------------------------------------------
   208     ManageEndOfCmdHandling( EFalse, ETrue, aClearInput );
   220     ManageEndOfCmdHandling( EFalse, ETrue, aClearInput );
   209     FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") ));
   221     FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") ));
   210     }
   222     }
   211 
   223 
   212 // ---------------------------------------------------------------------------
   224 // ---------------------------------------------------------------------------
       
   225 // Sends a character to be echoed
       
   226 // ---------------------------------------------------------------------------
       
   227 //
       
   228 EXPORT_C TInt CDunAtCmdHandler::SendEchoCharacter( const TDesC8* aInput,
       
   229                                                    MDunAtCmdEchoer* aCallback )
       
   230     {
       
   231     FTRACE(FPrint( _L("CDunAtCmdHandler::SendEchoCharacter()") ));
       
   232     TInt retVal = iCmdEchoer->SendEchoCharacter( aInput, aCallback );
       
   233     FTRACE(FPrint( _L("CDunAtCmdHandler::SendEchoCharacter() complete") ));
       
   234     return retVal;
       
   235     }
       
   236 
       
   237 // ---------------------------------------------------------------------------
   213 // Stops sending of AT command from parse buffer
   238 // Stops sending of AT command from parse buffer
   214 // ---------------------------------------------------------------------------
   239 // ---------------------------------------------------------------------------
   215 //
   240 //
   216 EXPORT_C TInt CDunAtCmdHandler::Stop()
   241 EXPORT_C TInt CDunAtCmdHandler::Stop()
   217     {
   242     {
   221         {
   246         {
   222         FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() (not ready) complete" )));
   247         FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() (not ready) complete" )));
   223         return KErrNotReady;
   248         return KErrNotReady;
   224         }
   249         }
   225     iCmdPusher->Stop();
   250     iCmdPusher->Stop();
   226     iHandleState = EDunStateIdle;
   251     // The line below is used in the case when this function is called by
       
   252     // CDunUpstream as a result of "data mode ON" change notification.
       
   253     // In this case it is possible that HandleNextDecodedCommand() returns
       
   254     // without resetting the iInputBuffer because of the way it checks the
       
   255     // iHandleState.
       
   256     ManageEndOfCmdHandling( EFalse, ETrue, ETrue );
   227     FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") ));
   257     FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") ));
   228     return KErrNone;
   258     return KErrNone;
   229     }
   259     }
   230 
   260 
   231 // ---------------------------------------------------------------------------
   261 // ---------------------------------------------------------------------------
   311         }
   341         }
   312     // Create the array of special commands
   342     // Create the array of special commands
   313     CreateSpecialCommandsL();
   343     CreateSpecialCommandsL();
   314     // Create the plugin handlers
   344     // Create the plugin handlers
   315     CreatePluginHandlersL();
   345     CreatePluginHandlersL();
       
   346     // Create the echo handler
       
   347     iCmdEchoer = CDunAtCmdEchoer::NewL( iDownstream );
   316     // Create the listeners
   348     // Create the listeners
   317     CDunAtEcomListen* ecomListen = CDunAtEcomListen::NewLC( &iAtCmdExt, this );
   349     iEcomListen = CDunAtEcomListen::NewL( &iAtCmdExt, this );
   318     CDunAtModeListen* modeListen = CDunAtModeListen::NewLC( &iAtCmdExtCommon,
   350     iModeListen = CDunAtModeListen::NewL( &iAtCmdExtCommon, this );
   319                                                            this );
   351     iNvramListen = CDunAtNvramListen::NewL( &iAtCmdExt, &iAtCmdExtCommon );
   320     CDunAtNvramListen* nvramListen = CDunAtNvramListen::NewLC( &iAtCmdExt,
   352     iAtSpecialCmdHandler = CDunAtSpecialCmdHandler::NewL();
   321                                                                &iAtCmdExtCommon );
       
   322     // Set the default modes (+report) and characters
   353     // Set the default modes (+report) and characters
   323     GetAndSetDefaultSettingsL();
   354     GetAndSetDefaultSettingsL();
   324     // Start listening
   355     // Start listening
   325     ecomListen->IssueRequest();
   356     iEcomListen->IssueRequest();
   326     modeListen->IssueRequest();
   357     iModeListen->IssueRequest();
   327     nvramListen->IssueRequest();
   358     iNvramListen->IssueRequest();
   328     CleanupStack::Pop( nvramListen );
       
   329     CleanupStack::Pop( modeListen );
       
   330     CleanupStack::Pop( ecomListen );
       
   331     CleanupStack::Pop( &iAtCmdExtCommon );
   359     CleanupStack::Pop( &iAtCmdExtCommon );
   332     CleanupStack::Pop( &iAtCmdExt );
   360     CleanupStack::Pop( &iAtCmdExt );
   333     iEcomListen = ecomListen;
       
   334     iModeListen = modeListen;
       
   335     iNvramListen = nvramListen;
       
   336     
       
   337     iAtSpecialCmdHandler = CDunAtSpecialCmdHandler::NewL();
       
   338     FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() complete") ));
   361     FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() complete") ));
   339     }
   362     }
   340 
   363 
   341 // ---------------------------------------------------------------------------
   364 // ---------------------------------------------------------------------------
   342 // Initializes this class
   365 // Initializes this class
   354     iCommand = NULL;
   377     iCommand = NULL;
   355     iDecodeInfo.iFirstDecode = ETrue;
   378     iDecodeInfo.iFirstDecode = ETrue;
   356     iDecodeInfo.iDecodeIndex = KErrNotFound;
   379     iDecodeInfo.iDecodeIndex = KErrNotFound;
   357     iDecodeInfo.iPrevChar = 0;
   380     iDecodeInfo.iPrevChar = 0;
   358     iDecodeInfo.iPrevExists = EFalse;
   381     iDecodeInfo.iPrevExists = EFalse;
       
   382     iEditorModeInfo.iContentFound = EFalse;
   359     iCmdPusher = NULL;
   383     iCmdPusher = NULL;
   360     iEcomListen = NULL;
   384     iEcomListen = NULL;
   361     iModeListen = NULL;
   385     iModeListen = NULL;
   362     iNvramListen = NULL;
   386     iNvramListen = NULL;
   363     iDataMode = EFalse;
   387     iDataMode = EFalse;
   789     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") ));
   813     FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") ));
   790     return EFalse;
   814     return EFalse;
   791     }
   815     }
   792 
   816 
   793 // ---------------------------------------------------------------------------
   817 // ---------------------------------------------------------------------------
   794 // Manages end of AT command handling
   818 // Finds the start of the next command
   795 // ---------------------------------------------------------------------------
   819 // ---------------------------------------------------------------------------
   796 //
   820 //
   797 void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal,
   821 TInt CDunAtCmdHandler::FindStartOfNextCommand()
   798                                                TBool aNotifyLocal,
   822     {
   799                                                TBool aClearInput )
   823     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand()") ));
   800     {
       
   801     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") ));
       
   802     if ( iInputBuffer.Length() > 0 )
       
   803         {
       
   804         iLastBuffer.Copy( iInputBuffer );
       
   805         }
       
   806     ResetParseBuffers( aClearInput );
       
   807     iHandleState = EDunStateIdle;
       
   808     if ( aNotifyLocal )
       
   809         {
       
   810         iCmdPusher->SetEndOfCmdLine();
       
   811         }
       
   812     if ( !aNotifyExternal )
       
   813         {
       
   814         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") ));
       
   815         return;
       
   816         }
       
   817     // Note: here we need to avoid internal recursion when parsing the
   824     // Note: here we need to avoid internal recursion when parsing the
   818     // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the
   825     // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the
   819     // same upstream block.
   826     // same upstream block.
   820     // Skip all the extra markers except the one we already know to exist.
   827     // Skip all the extra markers except the one we already know to exist.
   821     TInt i;
   828     TInt i;
   829             {
   836             {
   830             foundIndex = i;
   837             foundIndex = i;
   831             break;
   838             break;
   832             }
   839             }
   833         }
   840         }
       
   841     FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand() complete") ));
       
   842     return foundIndex;
       
   843     }
       
   844 
       
   845 // ---------------------------------------------------------------------------
       
   846 // Manages end of AT command handling
       
   847 // ---------------------------------------------------------------------------
       
   848 //
       
   849 void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal,
       
   850                                                TBool aNotifyLocal,
       
   851                                                TBool aClearInput )
       
   852     {
       
   853     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") ));
       
   854     if ( iInputBuffer.Length() > 0 )
       
   855         {
       
   856         iLastBuffer.Copy( iInputBuffer );
       
   857         }
       
   858     ResetParseBuffers( aClearInput );
       
   859     iHandleState = EDunStateIdle;
       
   860     if ( aNotifyLocal )
       
   861         {
       
   862         iCmdPusher->SetEndOfCmdLine();
       
   863         }
       
   864     if ( !aNotifyExternal )
       
   865         {
       
   866         FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") ));
       
   867         return;
       
   868         }
       
   869     TInt foundIndex = FindStartOfNextCommand();
   834     iUpstream->NotifyAtCmdHandlingEnd( foundIndex );
   870     iUpstream->NotifyAtCmdHandlingEnd( foundIndex );
   835     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") ));
   871     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") ));
   836     }
   872     }
   837 
   873 
   838 // ---------------------------------------------------------------------------
   874 // ---------------------------------------------------------------------------
   921                                              TDunDecodeInfo& aOldInfo )
   957                                              TDunDecodeInfo& aOldInfo )
   922     {
   958     {
   923     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo()") ));
   959     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo()") ));
   924     if ( aPeek )
   960     if ( aPeek )
   925         {
   961         {
       
   962         iEditorModeInfo.iPeekInfo = iDecodeInfo;
   926         iDecodeInfo = aOldInfo;
   963         iDecodeInfo = aOldInfo;
   927         }
   964         }
   928     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") ));
   965     FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") ));
   929     }
   966     }
   930 
   967 
  1527         }
  1564         }
  1528     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() complete" ) ));
  1565     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() complete" ) ));
  1529     }
  1566     }
  1530 
  1567 
  1531 // ---------------------------------------------------------------------------
  1568 // ---------------------------------------------------------------------------
       
  1569 // Manages editor mode reply
       
  1570 // ---------------------------------------------------------------------------
       
  1571 //
       
  1572 TInt CDunAtCmdHandler::ManageEditorModeReply( TBool aStart )
       
  1573     {
       
  1574     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply()" ) ));
       
  1575     // Two modes possible here:
       
  1576     // 1) Sending data directly from DTE to DCE, i.e. no subsequent data in
       
  1577     //    the input buffer -> Reissue read request from DTE.
       
  1578     // 2) Sending data from input buffer to DCE -> Do not reissue read request
       
  1579     //    from DTE: send the data in a loop
       
  1580     // In summary: send data byte-by-byte in editor mode until end of input.
       
  1581     // When end of input notify CDunUpstream to reissue the read request.
       
  1582     TBool nextContentFound = FindNextContent( aStart );
       
  1583     if ( !nextContentFound )
       
  1584         {
       
  1585         iUpstream->NotifyEditorModeReply( aStart );
       
  1586         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") ));
       
  1587         return KErrNone;
       
  1588         }
       
  1589     // In block mode end the block mode by sending <ESC> and hope it works.
       
  1590     iEscapeBuffer.Zero();
       
  1591     iEscapeBuffer.Append( KDunEscape );
       
  1592     iCmdPusher->IssueRequest( iEscapeBuffer, EFalse );
       
  1593     FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply() complete" ) ));
       
  1594     return KErrNone;
       
  1595     }
       
  1596 
       
  1597 // ---------------------------------------------------------------------------
       
  1598 // Finds the next content from the input data
       
  1599 // ---------------------------------------------------------------------------
       
  1600 //
       
  1601 TBool CDunAtCmdHandler::FindNextContent( TBool aStart )
       
  1602     {
       
  1603     FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent()" ) ));
       
  1604     if ( !aStart )
       
  1605         {
       
  1606         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (skip) complete" ) ));
       
  1607         return iEditorModeInfo.iContentFound;
       
  1608         }
       
  1609     iEditorModeInfo.iContentFound = EFalse;
       
  1610     TInt foundCmdIndex = KErrNotFound;
       
  1611     TBool nextContentFound = ExtractNextDecodedCommand( ETrue );  // peek
       
  1612     if ( !nextContentFound )
       
  1613         {
       
  1614         // Check the next subblock
       
  1615         foundCmdIndex = FindStartOfNextCommand();
       
  1616         }
       
  1617     if ( !nextContentFound && foundCmdIndex<0 )
       
  1618         {
       
  1619         FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (not found) complete") ));
       
  1620         return EFalse;
       
  1621         }
       
  1622     iEditorModeInfo.iContentFound = ETrue;
       
  1623     FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() complete" ) ));
       
  1624     return ETrue;
       
  1625     }
       
  1626 
       
  1627 // ---------------------------------------------------------------------------
  1532 // From class MDunAtCmdPusher.
  1628 // From class MDunAtCmdPusher.
  1533 // Notifies about end of AT command processing. This is after all reply data
  1629 // Notifies about end of AT command processing. This is after all reply data
  1534 // for an AT command is multiplexed to the downstream.
  1630 // for an AT command is multiplexed to the downstream.
  1535 // ---------------------------------------------------------------------------
  1631 // ---------------------------------------------------------------------------
  1536 //
  1632 //
  1537 TInt CDunAtCmdHandler::NotifyEndOfProcessing( TInt /*aError*/ )
  1633 TInt CDunAtCmdHandler::NotifyEndOfProcessing( TInt /*aError*/ )
  1538     {
  1634     {
  1539     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing()" ) ));
  1635     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing()" ) ));
       
  1636     TBool editorMode = iCmdPusher->EditorMode();
       
  1637     if ( editorMode )
       
  1638         {
       
  1639         ManageEditorModeReply( ETrue );
       
  1640         FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() (editor) complete" ) ));
       
  1641         return KErrNone;
       
  1642         }
  1540     HandleNextDecodedCommand();
  1643     HandleNextDecodedCommand();
  1541     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) ));
  1644     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) ));
  1542     return KErrNone;
  1645     return KErrNone;
  1543     }
  1646     }
  1544 
  1647 
  1566     {
  1669     {
  1567     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") ));
  1670     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") ));
  1568     TBool extracted = ExtractNextDecodedCommand( ETrue );
  1671     TBool extracted = ExtractNextDecodedCommand( ETrue );
  1569     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") ));
  1672     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") ));
  1570     return extracted;
  1673     return extracted;
       
  1674     }
       
  1675 
       
  1676 // ---------------------------------------------------------------------------
       
  1677 // From class MDunAtCmdPusher.
       
  1678 // Notifies about editor mode reply
       
  1679 // ---------------------------------------------------------------------------
       
  1680 //
       
  1681 TInt CDunAtCmdHandler::NotifyEditorModeReply()
       
  1682     {
       
  1683     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply()") ));
       
  1684     TInt retVal = ManageEditorModeReply( EFalse );
       
  1685     FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") ));
       
  1686     return retVal;
  1571     }
  1687     }
  1572 
  1688 
  1573 // ---------------------------------------------------------------------------
  1689 // ---------------------------------------------------------------------------
  1574 // From class MDunAtEcomListen.
  1690 // From class MDunAtEcomListen.
  1575 // Notifies about new plugin installation
  1691 // Notifies about new plugin installation