# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1282203999 -10800 # Node ID 3dcb815346df5062ad1be5f8159efe29fa3f6bd5 # Parent 7e0ecb5b116adfa129327b244e1c022cb29ca033 Revision: 201031 Kit: 201033 diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/bwins/dunatextu.def --- a/localconnectivityservice/dun/atext/bwins/dunatextu.def Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/bwins/dunatextu.def Thu Aug 19 10:46:39 2010 +0300 @@ -1,12 +1,11 @@ EXPORTS - ?StopUrc@CDunAtCmdHandler@@QAEHXZ @ 1 NONAME ; int CDunAtCmdHandler::StopUrc(void) - ?Stop@CDunAtCmdHandler@@QAEHXZ @ 2 NONAME ; int CDunAtCmdHandler::Stop(void) - ?SetEndOfCmdLine@CDunAtCmdHandler@@QAEXH@Z @ 3 NONAME ; void CDunAtCmdHandler::SetEndOfCmdLine(int) - ?ResetData@CDunAtCmdHandler@@QAEXXZ @ 4 NONAME ; void CDunAtCmdHandler::ResetData(void) - ?AddCmdModeCallback@CDunAtCmdHandler@@QAEHPAVMDunCmdModeMonitor@@@Z @ 5 NONAME ; int CDunAtCmdHandler::AddCmdModeCallback(class MDunCmdModeMonitor *) - ?NewL@CDunAtCmdHandler@@SAPAV1@PAVMDunAtCmdStatusReporter@@PAVMDunStreamManipulator@@PBVTDesC8@@@Z @ 6 NONAME ; class CDunAtCmdHandler * CDunAtCmdHandler::NewL(class MDunAtCmdStatusReporter *, class MDunStreamManipulator *, class TDesC8 const *) - ?ParseCommand@CDunAtCmdHandler@@QAEHAAVTDesC8@@AAH@Z @ 7 NONAME ; int CDunAtCmdHandler::ParseCommand(class TDesC8 &, int &) - ?StartUrc@CDunAtCmdHandler@@QAEHXZ @ 8 NONAME ; int CDunAtCmdHandler::StartUrc(void) - ?ManageAbortRequest@CDunAtCmdHandler@@QAEHXZ @ 9 NONAME ; int CDunAtCmdHandler::ManageAbortRequest(void) - ?SendEchoCharacter@CDunAtCmdHandler@@QAEHPBVTDesC8@@PAVMDunAtCmdEchoer@@@Z @ 10 NONAME ; int CDunAtCmdHandler::SendEchoCharacter(class TDesC8 const *, class MDunAtCmdEchoer *) + ?AddCmdModeCallback@CDunAtCmdHandler@@QAEHPAVMDunCmdModeMonitor@@@Z @ 1 NONAME ; int CDunAtCmdHandler::AddCmdModeCallback(class MDunCmdModeMonitor *) + ?AddDataForParsing@CDunAtCmdHandler@@QAEHAAVTDesC8@@AAH@Z @ 2 NONAME ; int CDunAtCmdHandler::AddDataForParsing(class TDesC8 &, int &) + ?ManageAbortRequest@CDunAtCmdHandler@@QAEHXZ @ 3 NONAME ; int CDunAtCmdHandler::ManageAbortRequest(void) + ?NewL@CDunAtCmdHandler@@SAPAV1@PAVMDunAtCmdStatusReporter@@PAVMDunStreamManipulator@@PBVTDesC8@@@Z @ 4 NONAME ; class CDunAtCmdHandler * CDunAtCmdHandler::NewL(class MDunAtCmdStatusReporter *, class MDunStreamManipulator *, class TDesC8 const *) + ?ResetData@CDunAtCmdHandler@@QAEXXZ @ 5 NONAME ; void CDunAtCmdHandler::ResetData(void) + ?SendEchoCharacter@CDunAtCmdHandler@@QAEHPBVTDesC8@@PAVMDunAtCmdEchoer@@@Z @ 6 NONAME ; int CDunAtCmdHandler::SendEchoCharacter(class TDesC8 const *, class MDunAtCmdEchoer *) + ?StartUrc@CDunAtCmdHandler@@QAEHXZ @ 7 NONAME ; int CDunAtCmdHandler::StartUrc(void) + ?Stop@CDunAtCmdHandler@@QAEHXZ @ 8 NONAME ; int CDunAtCmdHandler::Stop(void) + ?StopUrc@CDunAtCmdHandler@@QAEHXZ @ 9 NONAME ; int CDunAtCmdHandler::StopUrc(void) diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/eabi/dunatextu.def --- a/localconnectivityservice/dun/atext/eabi/dunatextu.def Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/eabi/dunatextu.def Thu Aug 19 10:46:39 2010 +0300 @@ -1,12 +1,11 @@ EXPORTS - _ZN16CDunAtCmdHandler12ParseCommandER6TDesC8Ri @ 1 NONAME - _ZN16CDunAtCmdHandler15SetEndOfCmdLineEi @ 2 NONAME + _ZN16CDunAtCmdHandler17AddDataForParsingER6TDesC8Ri @ 1 NONAME + _ZN16CDunAtCmdHandler17SendEchoCharacterEPK6TDesC8P15MDunAtCmdEchoer @ 2 NONAME _ZN16CDunAtCmdHandler18AddCmdModeCallbackEP18MDunCmdModeMonitor @ 3 NONAME - _ZN16CDunAtCmdHandler4NewLEP23MDunAtCmdStatusReporterP21MDunStreamManipulatorPK6TDesC8 @ 4 NONAME - _ZN16CDunAtCmdHandler4StopEv @ 5 NONAME - _ZN16CDunAtCmdHandler7StopUrcEv @ 6 NONAME - _ZN16CDunAtCmdHandler8StartUrcEv @ 7 NONAME - _ZN16CDunAtCmdHandler9ResetDataEv @ 8 NONAME - _ZN16CDunAtCmdHandler18ManageAbortRequestEv @ 9 NONAME - _ZN16CDunAtCmdHandler17SendEchoCharacterEPK6TDesC8P15MDunAtCmdEchoer @ 10 NONAME + _ZN16CDunAtCmdHandler18ManageAbortRequestEv @ 4 NONAME + _ZN16CDunAtCmdHandler4NewLEP23MDunAtCmdStatusReporterP21MDunStreamManipulatorPK6TDesC8 @ 5 NONAME + _ZN16CDunAtCmdHandler4StopEv @ 6 NONAME + _ZN16CDunAtCmdHandler7StopUrcEv @ 7 NONAME + _ZN16CDunAtCmdHandler8StartUrcEv @ 8 NONAME + _ZN16CDunAtCmdHandler9ResetDataEv @ 9 NONAME diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtCmdEchoer.h --- a/localconnectivityservice/dun/atext/inc/DunAtCmdEchoer.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtCmdEchoer.h Thu Aug 19 10:46:39 2010 +0300 @@ -105,7 +105,7 @@ * From MDunCompletionReporter. * Gets called when data push is complete * - * @since S60 5.0 + * @since TB9.2 * @param aAllPushed ETrue if all in the queue were pushed, EFalse otherwise * @return None */ diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtCmdHandler.h --- a/localconnectivityservice/dun/atext/inc/DunAtCmdHandler.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtCmdHandler.h Thu Aug 19 10:46:39 2010 +0300 @@ -32,7 +32,7 @@ const TInt KDunChSetMaxCharLen = 1; // Only ASCII supported for now const TInt KDunOkBufLength = 1+1+2+1+1; // ++"OK"++ const TInt KDunErrorBufLength = 1+1+5+1+1; // ++"ERROR"++ -const TInt KDunInputBufLength = (512 + 1); // 512 chars for command + +const TInt KDunLineBufLength = (512 + 1); // 512 chars for command + const TInt KDunEscBufLength = 1; // Escape (0x1B) character class CDunAtUrcHandler; @@ -43,7 +43,7 @@ * Class used for storing information related to string conversion and parsing * * @lib dunatext.lib - * @since S60 v3.2 + * @since TB9.2 */ NONSHARABLE_CLASS( TDunParseInfo ) { @@ -51,9 +51,10 @@ public: /** - * Buffer for sending + * Buffer for sending to ATEXT (one command) + * (length is part of KDunLineBufLength) */ - TBuf8 iSendBuffer; + TBuf8 iSendBuffer; /** * Conversion limit for upper case conversion. @@ -68,7 +69,7 @@ * Class used for AT command decoding related functionality * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( TDunDecodeInfo ) { @@ -81,12 +82,12 @@ TBool iFirstDecode; /** - * Index in iInputBuffer for decoding to iDecodeBuffer + * Index in iLineBuffer for decoding to iSendBuffer */ TInt iDecodeIndex; /** - * Index in iInputBuffer for extended character position + * Index in iLineBuffer for extended character position */ TInt iExtendedIndex; @@ -106,7 +107,7 @@ TBool iAssignFound; /** - * Flag to indicate if processing inside quotes + * Flag to indicate if processing inside quotes */ TBool iInQuotes; @@ -114,11 +115,11 @@ * Flag to indicate if special subcommand found */ TBool iSpecialFound; - + /** - * Buffer for parsing + * Number of commands handled (for debugging purposes) */ - TBuf8 iDecodeBuffer; + TBool iCmdsHandled; }; @@ -140,7 +141,7 @@ /** * AT command decoding related information for peeked data - * (not to be used if HandleNextDecodedCommand() returns EFalse) + * (not to be used if HandleNextSubCommand() returns EFalse) */ TDunDecodeInfo iPeekInfo; @@ -150,7 +151,7 @@ * Notification interface class for command mode start/end * * @lib dunutils.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( MDunCmdModeMonitor ) { @@ -160,7 +161,7 @@ /** * Notifies about command mode start * - * @since S60 5.0 + * @since TB9.2 * @return None */ virtual void NotifyCommandModeStart() = 0; @@ -168,7 +169,7 @@ /** * Notifies about command mode end * - * @since S60 5.0 + * @since TB9.2 * @return None */ virtual void NotifyCommandModeEnd() = 0; @@ -179,7 +180,7 @@ * Notification interface class for status changes in AT command handling * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( MDunAtCmdStatusReporter ) { @@ -187,21 +188,12 @@ public: /** - * Notifies about AT command handling start + * Notifies about parser's need to get more data * - * @since S60 5.0 + * @since TB9.2 * @return None */ - virtual void NotifyAtCmdHandlingStart() = 0; - - /** - * Notifies about AT command handling end - * - * @since S60 5.0 - * @param aEndIndex Index to the start of next command - * @return None - */ - virtual void NotifyAtCmdHandlingEnd( TInt aStartIndex ) = 0; + virtual void NotifyParserNeedsMoreData() = 0; /** * Notifies about editor mode reply @@ -218,7 +210,7 @@ * Class for AT command handler and notifier * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( CDunAtCmdHandler ) : public CBase, public MDunAtCmdPusher, @@ -248,7 +240,7 @@ /** * Resets data to initial values * - * @since S60 5.0 + * @since TB9.2 * @return None */ IMPORT_C void ResetData(); @@ -257,41 +249,31 @@ * Adds callback for command mode notification * The callback will be called when command mode starts or ends * - * @since S60 5.0 + * @since TB9.2 * @param aCallback Callback to call when command mode starts or ends * @return Symbian error code on error, KErrNone otherwise */ IMPORT_C TInt AddCmdModeCallback( MDunCmdModeMonitor* aCallback ); /** - * Parses an AT command + * Adds data for parsing and parses if necessary * - * @since S60 5.0 - * @param aCommand Command to parse - * @param aPartialInput ETrue if partial input, EFalse otherwise + * @since TB9.2 + * @param aInput Data to add for parsing + * @param aMoreNeeded ETrue if more data needed, EFalse otherwise * @return Symbian error code on error, KErrNone otherwise */ - IMPORT_C TInt ParseCommand( TDesC8& aCommand, TBool& aPartialInput ); + IMPORT_C TInt AddDataForParsing( TDesC8& aInput, TBool& aMoreNeeded ); /** * Manages request to abort command handling * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ IMPORT_C TInt ManageAbortRequest(); /** - * Sets end of command line marker on for the possible series of AT - * commands. - * - * @since S60 5.0 - * @param aClearInput ETrue to clear input buffer, EFalse otherwise - * @return None - */ - IMPORT_C void SetEndOfCmdLine( TBool aClearInput ); - - /** * Sends a character to be echoed * * @since TB9.2 @@ -305,7 +287,7 @@ /** * Stops sending of AT command from decode buffer * - * @since S60 3.2 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ IMPORT_C TInt Stop(); @@ -313,7 +295,7 @@ /** * Starts URC message handling * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ IMPORT_C TInt StartUrc(); @@ -321,7 +303,7 @@ /** * Stops URC message handling * - * @since S60 3.2 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ IMPORT_C TInt StopUrc(); @@ -337,7 +319,7 @@ /** * Initializes this class * - * @since S60 3.2 + * @since TB9.2 * @return None */ void Initialize(); @@ -345,7 +327,7 @@ /** * Creates plugin handlers for this class * - * @since S60 5.0 + * @since TB9.2 * @return None */ void CreatePluginHandlersL(); @@ -353,7 +335,7 @@ /** * Creates the array of special commands * - * @since S60 5.0 + * @since TB9.2 * @return None */ void CreateSpecialCommandsL(); @@ -362,7 +344,7 @@ * Recreates special command data. * This is done when a plugin is installed or uninstalled. * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt RecreateSpecialCommands(); @@ -370,7 +352,7 @@ /** * Gets default settings from RATExtCommon and sets them to RATExt * - * @since S60 5.0 + * @since TB9.2 * @return None */ void GetAndSetDefaultSettingsL(); @@ -378,7 +360,7 @@ /** * Regenerates the reply strings based on settings * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if quiet mode, EFalse otherwise */ TBool RegenerateReplyStrings(); @@ -386,7 +368,7 @@ /** * Regenerates the ok reply based on settings * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if quiet mode, EFalse otherwise */ TBool RegenerateOkReply(); @@ -394,7 +376,7 @@ /** * Regenerates the error reply based on settings * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if quiet mode, EFalse otherwise */ TBool RegenerateErrorReply(); @@ -402,7 +384,7 @@ /** * Gets current mode * - * @since S60 5.0 + * @since TB9.2 * @param aMask Mask for current mode (only one supported) * @return New current mode */ @@ -412,7 +394,7 @@ * Instantiates one URC message handling class instance and adds it to * the URC message handler array * - * @since S60 3.2 + * @since TB9.2 * @return None */ CDunAtUrcHandler* AddOneUrcHandlerL(); @@ -420,7 +402,7 @@ /** * Deletes all instantiated URC message handlers * - * @since S60 5.0 + * @since TB9.2 * @return None */ void DeletePluginHandlers(); @@ -428,86 +410,131 @@ /** * Manages partial AT command * - * @since S60 5.0 - * @param aCommand Command to process - * @param aNeedsCarriage ETrue if full and non-consumed AT command needs - * carriage return (AT command "A/") - * @return ETrue if no other processing needed, EFalse otherwise + * @since TB9.2 + * @return ETrue if more data needed, EFalse otherwise */ - TBool ManagePartialCommand( TDesC8& aCommand, - TBool& aNeedsCarriage ); + TBool ManagePartialCommand(); /** * Echoes a command if echo is on * - * @since S60 5.0 - * @param aDes String descriptor + * @since TB9.2 * @return ETrue if echo push started, EFalse otherwise */ - TBool EchoCommand( TDesC8& aDes ); + TBool EchoCommand(); /** * Handles backspace and cancel characters * - * @since S60 5.0 - * @param aCommand Command to process + * @since TB9.2 * @return ETrue if special character found, EFalse otherwise */ - TBool HandleSpecialCharacters( TDesC8& aCommand ); + TBool HandleSpecialCharacters(); + + /** + * Extracts line from input buffer to line buffer + * + * @since TB9.2 + * @return ETrue if more data needed, EFalse otherwise + */ + TBool ExtractLineFromInputBuffer(); + + /** + * Handles generic buffer management + * (explanation in ExtractLineFromInputBuffer()) + * + * @since TB9.2 + * @param aStartIndex Start index for buffer to be copied + * @param aCopyLength Length for data needed to be copied + * @param aCopyNeeded ETrue if buffer copy needed + * @return ETrue if more data needed, EFalse otherwise + */ + TBool HandleGenericBufferManagement( TInt& aStartIndex, + TInt& aCopyLength, + TBool& aCopyNeeded ); + + /** + * Handles special buffer management + * (explanation in ExtractLineFromInputBuffer()) + * + * @since TB9.2 + * @param aStartIndex Start index for buffer to be copied + * @param aCopyLength Length for data needed to be copied + * @param aCopyNeeded ETrue if buffer copy needed + * @return ETrue if more data needed, EFalse otherwise + */ + TBool HandleSpecialBufferManagement( TInt aStartIndex, + TInt& aCopyLength, + TBool& aCopyNeeded ); /** - * Appends command to input buffer + * Skips end-of-line characters + * + * @since TB9.2 + * @param aStartIndex Start index + * @return Index to end of non-end-of-line or Symbian error code on error + */ + TInt SkipEndOfLineCharacters( TInt aStartIndex ); + + /** + * Skips subcommand delimiter characters * - * @since S60 5.0 - * @param aCommand Command to append to input buffer - * @param aEndFound ETrue if end (carriage return) was found - * @return ETrue if overflow was found, EFalse otherwise + * @since TB9.2 + * @param aStartIndex Start index + * @return Index to end of delimiter or Symbian error code on error */ - TBool AppendCommandToInputBuffer( TDesC8& aCommand, TBool& aEndFound ); + TInt SkipSubCommandDelimiterCharacters( TInt aStartIndex ); + + /** + * Finds the end of the line + * + * @since TB9.2 + * @param aStartIndex Start index + * @return Index to end of line or Symbian error code on error + */ + TInt FindEndOfLine( TInt aStartIndex ); /** - * Handles next decoded command from input buffer + * Handles next subcommand from line buffer * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if last command decoded, EFalse otherwise */ - TBool HandleNextDecodedCommand(); + TBool HandleNextSubCommand(); /** - * Finds the start of the next command + * Manages end of AT command handling + * + * @since TB9.2 + * @param aNotifyLocal Notify local parties + * @param aNotifyExternal Notify external parties + * @return None + */ + void ManageEndOfCmdHandling( TBool aNotifyLocal, + TBool aNotifyExternal ); + + /** + * Extracts next subcommand from line buffer to send buffer + * + * @since TB9.2 + * @param aPeek Peek for the next command if ETrue, EFalse otherwise + * @return ETrue if command extracted, EFalse otherwise + */ + TBool ExtractNextSubCommand( TBool aPeek=EFalse ); + + /** + * Finds the start of subcommand from line buffer * * @since TB9.2 * @return Index to the next command or Symbian error code on error */ - TInt FindStartOfNextCommand(); + TInt FindStartOfSubCommand(); /** - * Manages end of AT command handling - * - * @since S60 5.0 - * @param aNotifyExternal Notify external parties - * @param aNotifyLocal Notify local parties - * @param aClearInput ETrue to clear input buffer, EFalse otherwise - * @return None - */ - void ManageEndOfCmdHandling( TBool aNotifyExternal, - TBool aNotifyLocal, - TBool aClearInput ); - - /** - * Extracts next decoded command from input buffer to decode buffer - * - * @since S60 5.0 - * @param aPeek Peek for the next command if ETrue, EFalse otherwise - * @return ETrue if command extracted, EFalse otherwise - */ - TBool ExtractNextDecodedCommand( TBool aPeek=EFalse ); - - /** - * Restores old decode info. For ExtractNextDecodedCommand() when aPeeks is + * Restores old decode info. For ExtractNextSubCommand() when aPeeks is * ETrue. * - * @since S60 5.0 + * @since TB9.2 * @param aPeek Peek for the next command if ETrue, EFalse otherwise * @param aOldInfo Old information to restore when aPeek is ETrue * @return None @@ -515,39 +542,18 @@ void RestoreOldDecodeInfo( TBool aPeek, TDunDecodeInfo& aOldInfo ); /** - * Finds end of an AT command + * Tests for end of AT command line * - * @since S60 5.0 - * @param aDes String descriptor - * @param aStartIndex Start index for search - * @return Index if found, KErrNotFound otherwise - */ - TInt FindEndOfCommand( TDesC8& aDes, TInt aStartIndex=0 ); - - /** - * Tests for end of AT command character - * - * @since S60 5.0 + * @since TB9.2 * @param aCharacter Character to test * @return ETrue if end of command, EFalse otherwise */ - TBool IsEndOfCommand( TChar& aCharacter ); - - /** - * Finds start of a decoded AT command - * - * @since S60 5.0 - * @param aDes String descriptor - * @param aStartIndex Start index for search - * @return Index if found, KErrNotFound otherwise - */ - TInt FindStartOfDecodedCommand( TDesC8& aDes, - TInt aStartIndex ); + TBool IsEndOfLine( TChar& aCharacter ); /** * Checks if character is delimiter character * - * @since S60 5.0 + * @since TB9.2 * @param aCharacter Character to test * @return ETrue if delimiter character, EFalse otherwise */ @@ -556,7 +562,7 @@ /** * Checks if character is of extended group * - * @since S60 5.0 + * @since TB9.2 * @param aCharacter Character to test * @return ETrue if extended character, EFalse otherwise */ @@ -565,13 +571,11 @@ /** * Checks special command * - * @since S60 5.0 - * @param aStartIndex Start index (doesn't change) + * @since TB9.2 * @param aEndIndex End index (changes) * @return Symbian error code on error, KErrNone otherwise */ - TBool CheckSpecialCommand( TInt aStartIndex, - TInt& aEndIndex ); + TBool CheckSpecialCommand( TInt& aEndIndex ); /** * Saves character decode state for a found character @@ -584,7 +588,7 @@ */ void SaveFoundCharDecodeState( TChar aCharacter, TBool aAddSpecial=ETrue ); - + /** * Saves character decode state for a not found character * @@ -616,7 +620,7 @@ * @return ETrue if in next command's extended border, EFalse otherwise */ TBool IsExtendedBorder( TChar aCharacter, TInt aStartIndex, TInt& aEndIndex ); - + /** * Finds subcommand with alphanumeric borders * @@ -631,16 +635,15 @@ * Finds subcommand * * @since TB9.2 - * @param aStartIndex Start index (doesn't change) * @param aEndIndex End index (changes) * @return Symbian error code on error, KErrNone otherwise */ - TInt FindSubCommand( TInt aStartIndex, TInt& aEndIndex ); + TInt FindSubCommand( TInt& aEndIndex ); /** * Check if "A/" command * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if "A/" command, EFalse otherwise */ TBool IsASlashCommand(); @@ -648,24 +651,15 @@ /** * Handles "A/" command * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if error reply push started, EFalse otherwise */ TBool HandleASlashCommand(); /** - * Resets parse buffers - * - * @since S60 5.0 - * @param aClearInput ETrue to clear input buffer, EFalse otherwise - * @return None - */ - void ResetParseBuffers( TBool aClearInput=ETrue ); - - /** * Manages command mode change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Mode to manage * @return ETrue if command mode change detected, EFalse otherwise */ @@ -674,7 +668,7 @@ /** * Reports command mode start/end change * - * @since S60 3.2 + * @since TB9.2 * @param aStart Command mode start if ETrue, end otherwise * @return None */ @@ -683,7 +677,7 @@ /** * Manages echo mode change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Mode to manage * @return ETrue if echo mode change detected, EFalse otherwise */ @@ -692,7 +686,7 @@ /** * Manages quiet mode change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Mode to manage * @return ETrue if quiet mode change detected, EFalse otherwise */ @@ -701,7 +695,7 @@ /** * Manages verbose mode change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Mode to manage * @return ETrue if verbose mode change detected, EFalse otherwise */ @@ -710,7 +704,7 @@ /** * Manages character change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Mode to manage * @return None */ @@ -742,7 +736,7 @@ * This is after all reply data for an AT command is multiplexed to the * downstream. * - * @since S60 5.0 + * @since TB9.2 * @param aError Error code of command processing completion * @return None */ @@ -752,15 +746,15 @@ * Notifies about request to stop AT command handling for the rest of the * command line data * - * @since S60 5.0 - * @return Symbian error code on error, KErrNone otherwise + * @since TB9.2 + * @return None */ - TInt NotifyEndOfCmdLineProcessing(); + void NotifyEndOfCmdLineProcessing(); /** * Notifies about request to peek for the next command * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if next command exists, EFalse otherwise */ TBool NotifyNextCommandPeekRequest(); @@ -789,7 +783,7 @@ * From MDunAtEcomListen. * Notifies about new plugin installation * - * @since S60 5.0 + * @since TB9.2 * @return None */ TInt NotifyPluginInstallation( TUid& aPluginUid ); @@ -798,7 +792,7 @@ * From MDunAtEcomListen. * Notifies about existing plugin uninstallation * - * @since S60 5.0 + * @since TB9.2 * @return None */ TInt NotifyPluginUninstallation( TUid& aPluginUid ); @@ -809,7 +803,7 @@ * From MDunAtModeListen. * Gets called on mode status change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Mode to manage * @return Symbian error code on error, KErrNone otherwise */ @@ -861,10 +855,10 @@ TInt8 iBackspace; /** - * Current command to ParseCommand() + * Current input to AddDataForParsing() * Not own. */ - TDesC8* iCommand; + TDesC8* iInput; /** * Special commands for parsing @@ -887,14 +881,14 @@ TBuf8 iErrorBuffer; /** - * Buffer for AT command input + * Buffer for AT command (one line) */ - TBuf8 iInputBuffer; + TBuf8 iLineBuffer; /** * Buffer for last AT command input (for "A/") */ - TBuf8 iLastBuffer; + TBuf8 iLastBuffer; /** * Buffer for command @@ -973,7 +967,7 @@ TBool iVerboseOn; /** - * End index for command delimiter + * End index for not added data in iCommand */ TInt iEndIndex; diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtCmdPusher.h --- a/localconnectivityservice/dun/atext/inc/DunAtCmdPusher.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtCmdPusher.h Thu Aug 19 10:46:39 2010 +0300 @@ -28,7 +28,7 @@ * Notification interface class for data pushing status changes * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( MDunAtCmdPusher ) { @@ -40,7 +40,7 @@ * This is after all reply data for an AT command is multiplexed to the * downstream. * - * @since S60 5.0 + * @since TB9.2 * @param aError Error code of command processing completion * @return Symbian error code on error, KErrNone otherwise */ @@ -50,15 +50,15 @@ * Notifies about request to stop AT command handling for the rest of the * command line data * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ - virtual TInt NotifyEndOfCmdLineProcessing() = 0; + virtual void NotifyEndOfCmdLineProcessing() = 0; /** * Notifies about request to peek for the next command * - * @since S60 5.0 + * @since TB9.2 * @return ETrue if next command exists, EFalse otherwise */ virtual TBool NotifyNextCommandPeekRequest() = 0; @@ -77,7 +77,7 @@ * Class for AT command URC handler * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( CDunAtCmdPusher ) : public CActive, public MDunCompletionReporter @@ -119,7 +119,7 @@ /** * Resets data to initial values * - * @since S60 5.0 + * @since TB9.2 * @return None */ void ResetData(); @@ -127,17 +127,17 @@ /** * Starts AT command handling * - * @since S60 5.0 - * @param aCommand AT command or editor mode input to handle + * @since TB9.2 + * @param aInput AT command or editor mode input to handle * @param aNormalMode ETrue if request issue for normal mode * @return Symbian error code on error, KErrNone otherwise */ - TInt IssueRequest( TDesC8& aCommand, TBool aNormalMode=ETrue ); + TInt IssueRequest( TDesC8& aInput, TBool aNormalMode=ETrue ); /** * Stops AT command handling * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt Stop(); @@ -145,7 +145,7 @@ /** * Manages request to abort command handling * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt ManageAbortRequest(); @@ -154,7 +154,7 @@ * Sets end of command line marker on for the possible series of AT * commands. * - * @since S60 5.0 + * @since TB9.2 * @param aPushLast ETrue to push last reply, EFalse otherwise * @return None */ @@ -180,7 +180,7 @@ /** * Initializes this class * - * @since S60 5.0 + * @since TB9.2 * @return None */ void Initialize(); @@ -188,7 +188,7 @@ /** * Sets state to idle and notifies about subcommand handling completion * - * @since S60 5.0 + * @since TB9.2 * @param aError Error code for completion * @return None */ @@ -198,7 +198,7 @@ * Checks if "OK" (verbose) or "0" (numeric) string or exists at the end of * buffer and removes it * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt CheckAndRemoveOkString(); @@ -206,7 +206,7 @@ /** * Sends reply data to downstream * - * @since S60 5.0 + * @since TB9.2 * @param aRecvBuffer ETrue if using receive buffer * EFalse if using "OK" buffer * @return None @@ -248,7 +248,7 @@ /** * Manages change in reply type * - * @since S60 5.0 + * @since TB9.2 * @return None */ void ManageReplyTypeChange(); @@ -259,7 +259,7 @@ * From CActive. * Gets called when AT command handled * - * @since S60 5.0 + * @since TB9.2 * @return None */ void RunL(); @@ -268,7 +268,7 @@ * From CActive. * Gets called on cancel * - * @since S60 5.0 + * @since TB9.2 * @return None */ void DoCancel(); @@ -279,7 +279,7 @@ * From MDunCompletionReporter. * Gets called when data push is complete * - * @since S60 5.0 + * @since TB9.2 * @param aAllPushed ETrue if all in the queue were pushed, EFalse otherwise * @return None */ diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtEcomListen.h --- a/localconnectivityservice/dun/atext/inc/DunAtEcomListen.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtEcomListen.h Thu Aug 19 10:46:39 2010 +0300 @@ -26,7 +26,7 @@ * Notification interface class for ECOM plugin interface status changes * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( MDunAtEcomListen ) { @@ -36,7 +36,7 @@ /** * Notifies about new plugin installation * - * @since S60 5.0 + * @since TB9.2 * @param aPluginUid UID of installed plugin * @return Symbian error code on error, KErrNone otherwise */ @@ -45,7 +45,7 @@ /** * Notifies about existing plugin uninstallation * - * @since S60 5.0 + * @since TB9.2 * @param aPluginUid UID of uninstalled plugin * @return Symbian error code on error, KErrNone otherwise */ @@ -57,7 +57,7 @@ * Class for ECom plugin install/uninstall/version listener * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( CDunAtEcomListen ) : public CActive { @@ -81,7 +81,7 @@ */ static CDunAtEcomListen* NewLC( RATExt* aAtCmdExt, MDunAtEcomListen* aCallback ); - + /** * Destructor. */ @@ -90,7 +90,7 @@ /** * Resets data to initial values * - * @since S60 5.0 + * @since TB9.2 * @return None */ void ResetData(); @@ -98,7 +98,7 @@ /** * Starts waiting for ECom plugin install/uninstall/version status changes * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt IssueRequest(); @@ -106,7 +106,7 @@ /** * Stops waiting for Ecom plugin install/uninstall/version status changes * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt Stop(); @@ -121,7 +121,7 @@ /** * Initializes this class * - * @since S60 5.0 + * @since TB9.2 * @return None */ void Initialize(); @@ -132,7 +132,7 @@ * From CActive. * Gets called when plugin installed, uninstalled or changed * - * @since S60 5.0 + * @since TB9.2 * @return None */ void RunL(); @@ -141,7 +141,7 @@ * From CActive. * Gets called on cancel * - * @since S60 5.0 + * @since TB9.2 * @return None */ void DoCancel(); diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtModeListen.h --- a/localconnectivityservice/dun/atext/inc/DunAtModeListen.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtModeListen.h Thu Aug 19 10:46:39 2010 +0300 @@ -27,7 +27,7 @@ * Notification interface class for modem's mode listener * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( MDunAtModeListen ) { @@ -37,7 +37,7 @@ /** * Notifies about mode status change * - * @since S60 5.0 + * @since TB9.2 * @param aMode Current modem modes * @return Symbian error code on error, KErrNone otherwise */ @@ -49,7 +49,7 @@ * Class for modem's mode listener and notifier * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( CDunAtModeListen ) : public CActive { @@ -82,7 +82,7 @@ /** * Resets data to initial values * - * @since S60 5.0 + * @since TB9.2 * @return None */ void ResetData(); @@ -90,7 +90,7 @@ /** * Issues request to start monitoring for mode status changes * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt IssueRequest(); @@ -98,7 +98,7 @@ /** * Stops monitoring for mode status changes * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt Stop(); @@ -113,7 +113,7 @@ /** * Initializes this class * - * @since S60 5.0 + * @since TB9.2 * @return None */ void Initialize(); @@ -124,7 +124,7 @@ * From CActive. * Gets called when mode changes * - * @since S60 5.0 + * @since TB9.2 * @return None */ void RunL(); @@ -133,7 +133,7 @@ * From CActive. * Gets called on cancel * - * @since S60 5.0 + * @since TB9.2 * @return None */ void DoCancel(); diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtNvramListen.h --- a/localconnectivityservice/dun/atext/inc/DunAtNvramListen.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtNvramListen.h Thu Aug 19 10:46:39 2010 +0300 @@ -26,7 +26,7 @@ * Class for AT NVRAM status change listener * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( CDunAtNvramListen ) : public CActive { @@ -61,7 +61,7 @@ /** * Resets data to initial values * - * @since S60 5.0 + * @since TB9.2 * @return None */ void ResetData(); @@ -69,7 +69,7 @@ /** * Starts waiting for NVRAM status changes * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt IssueRequest(); @@ -77,7 +77,7 @@ /** * Stops waiting for NVRAM status changes * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt Stop(); @@ -92,7 +92,7 @@ /** * Initializes this class * - * @since S60 5.0 + * @since TB9.2 * @return None */ void Initialize(); @@ -103,7 +103,7 @@ * From CActive. * Gets called when NVRAM has changed * - * @since S60 5.0 + * @since TB9.2 * @return None */ void RunL(); @@ -112,7 +112,7 @@ * From CActive. * Gets called on cancel * - * @since S60 5.0 + * @since TB9.2 * @return None */ void DoCancel(); diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtSpecialCmdHandler.h --- a/localconnectivityservice/dun/atext/inc/DunAtSpecialCmdHandler.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtSpecialCmdHandler.h Thu Aug 19 10:46:39 2010 +0300 @@ -21,7 +21,7 @@ #include #include -const TInt KInputBufLength = (512 + 1); // Set this the same as in KDunInputBufLength +const TInt KLineBufLength = (512 + 1); // Set this the same as in KDunLineBufLength /** * Class for special AT command handler @@ -98,7 +98,7 @@ /** * Buffer for temporary AT command input */ - TBuf8 iBuffer; + TBuf8 iBuffer; /** * Special commands for parsing diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/inc/DunAtUrcHandler.h --- a/localconnectivityservice/dun/atext/inc/DunAtUrcHandler.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/inc/DunAtUrcHandler.h Thu Aug 19 10:46:39 2010 +0300 @@ -28,7 +28,7 @@ * Class for AT command URC handler * * @lib dunatext.lib - * @since S60 v5.0 + * @since TB9.2 */ NONSHARABLE_CLASS( CDunAtUrcHandler ) : public CActive, public MDunCompletionReporter @@ -62,7 +62,7 @@ /** * Resets data to initial values * - * @since S60 5.0 + * @since TB9.2 * @return None */ void ResetData(); @@ -70,7 +70,7 @@ /** * Starts waiting for an incoming URC message * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt IssueRequest(); @@ -78,7 +78,7 @@ /** * Stops waiting for an incoming URC message * - * @since S60 5.0 + * @since TB9.2 * @return Symbian error code on error, KErrNone otherwise */ TInt Stop(); @@ -86,7 +86,7 @@ /** * UID of the owning plugin * - * @since S60 5.0 + * @since TB9.2 * @return UID of the owning plugin */ TUid OwnerUid(); @@ -101,7 +101,7 @@ /** * Initializes this class * - * @since S60 3.2 + * @since TB9.2 * @return None */ void Initialize(); @@ -112,7 +112,7 @@ * From CActive. * Gets called when URC command received * - * @since S60 3.2 + * @since TB9.2 * @return None */ void RunL(); @@ -121,7 +121,7 @@ * From CActive. * Gets called on cancel * - * @since S60 3.2 + * @since TB9.2 * @return None */ void DoCancel(); @@ -132,7 +132,7 @@ * From MDunCompletionReporter. * Gets called when data push is complete * - * @since S60 5.0 + * @since TB9.2 * @param aAllPushed ETrue if all in the queue were pushed, EFalse otherwise * @return None */ diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp --- a/localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/atext/src/DunAtCmdHandler.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -23,6 +23,24 @@ */ /* + * This file has the following functionality: + * 1) Line buffer filler: + * AddDataForParsing(), ManagePartialCommand(), ExtractLineFromInputBuffer(), + * etc. This buffer is used for parsing. These functions are used for + * splitter-combiner logic described below. CDunAtCmdPusher is used + * separately for each element in the line buffer. + * 2) Parser and splitter-combiner to handle the separater elements (subcommands) + * in the line buffer. When end of line is detected, iEndIndex is used to + * extract the next line in iInput to the line buffer (ManageEndOfCmdHandling() + * and ExtractLineFromInputBuffer()). + * 3) When end of iEndIndex is found (ExtractLineFromInputBuffer()), more data + * is asked from CDunUpstream. + * Note: There is separate handling for "one character input data" and "A/" + * command handling which should be supported only for one line based data + * (ManagePartialCommand()). + */ + +/* * The AT command handling is splitted to two parts on high level: * 1) Splitter: splitting the sub-commands in a command line to multiple ones * for ATEXT to process. @@ -30,6 +48,13 @@ * (the filter categories are explained in DunAtCmdPusher.cpp) */ +/* + * Note1: This file uses AT command parsing based on heuristics. + * Refer to test specification if planning to change the heuristic. + * Note2: Input buffer management (ExtractLineFromInputBuffer()) can be tested + * with non-line based terminals such as HyperTerminal or Realterm. + */ + #include "DunAtCmdHandler.h" #include "DunAtUrcHandler.h" #include "DunDownstream.h" @@ -139,39 +164,38 @@ } // --------------------------------------------------------------------------- -// Parses an AT command +// Adds data for parsing and parses if necessary // --------------------------------------------------------------------------- // -EXPORT_C TInt CDunAtCmdHandler::ParseCommand( TDesC8& aCommand, - TBool& aPartialInput ) +EXPORT_C TInt CDunAtCmdHandler::AddDataForParsing( TDesC8& aInput, + TBool& aMoreNeeded ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") )); - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") )); - FTRACE(FPrintRaw(aCommand) ); + FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing()") )); + FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() received (%d bytes):"), aInput.Length() )); + FTRACE(FPrintRaw(aInput) ); TBool editorMode = iCmdPusher->EditorMode(); if ( editorMode ) { - // Note: return here with "no partial input" and some error to fool + // Note: return here with "no more data needed" and some error to fool // CDunUpstream into not reissuing the read request. - iCmdPusher->IssueRequest( aCommand, EFalse ); - aPartialInput = EFalse; + iCmdPusher->IssueRequest( aInput, EFalse ); + aMoreNeeded = EFalse; return KErrGeneral; } - iCommand = &aCommand; // iCommand only for normal mode + iInput = &aInput; // iInput only for normal mode // Manage partial AT command - TBool needsCarriage = ETrue; - TBool okToExit = ManagePartialCommand( aCommand, needsCarriage ); - if ( okToExit ) + TBool moreNeeded = ManagePartialCommand(); + if ( moreNeeded ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (ok to exit) complete") )); - aPartialInput = ETrue; + aMoreNeeded = ETrue; + FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() (more partial) complete") )); return KErrNone; } if ( iHandleState != EDunStateIdle ) { - aPartialInput = EFalse; - ResetParseBuffers(); - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not ready) complete") )); + aMoreNeeded = EFalse; + ManageEndOfCmdHandling( EFalse, EFalse ); + FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() (not ready) complete") )); return KErrNotReady; } TBool pushStarted = HandleASlashCommand(); @@ -180,20 +204,21 @@ // Note: return here with "partial input" status to fool CDunUpstream // into reissuing the read request. The AT command has not really // started yet so this is necessary. - aPartialInput = ETrue; - ResetParseBuffers(); - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (A/) complete") )); + aMoreNeeded = ETrue; + ManageEndOfCmdHandling( EFalse, EFalse ); + FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() (A/) complete") )); return KErrNone; } - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received total:") )); - FTRACE(FPrintRaw(iInputBuffer) ); iHandleState = EDunStateAtCmdHandling; - iUpstream->NotifyAtCmdHandlingStart(); iDecodeInfo.iFirstDecode = ETrue; iDecodeInfo.iDecodeIndex = 0; - HandleNextDecodedCommand(); - FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() complete") )); - aPartialInput = EFalse; + iDecodeInfo.iPrevExists = EFalse; + iParseInfo.iLimit = KErrNotFound; + iParseInfo.iSendBuffer.Zero(); + iEditorModeInfo.iContentFound = EFalse; + HandleNextSubCommand(); + FTRACE(FPrint( _L("CDunAtCmdHandler::AddDataForParsing() complete") )); + aMoreNeeded = EFalse; return KErrNone; } @@ -211,17 +236,6 @@ } // --------------------------------------------------------------------------- -// Sets end of command line marker on for the possible series of AT commands. -// --------------------------------------------------------------------------- -// -EXPORT_C void CDunAtCmdHandler::SetEndOfCmdLine( TBool aClearInput ) - { - FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine()") )); - ManageEndOfCmdHandling( EFalse, ETrue, aClearInput ); - FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") )); - } - -// --------------------------------------------------------------------------- // Sends a character to be echoed // --------------------------------------------------------------------------- // @@ -250,10 +264,10 @@ iCmdPusher->Stop(); // The line below is used in the case when this function is called by // CDunUpstream as a result of "data mode ON" change notification. - // In this case it is possible that HandleNextDecodedCommand() returns - // without resetting the iInputBuffer because of the way it checks the + // In this case it is possible that HandleNextSubCommand() returns + // without resetting the iSendBuffer because of the way it checks the // iHandleState. - ManageEndOfCmdHandling( EFalse, ETrue, ETrue ); + ManageEndOfCmdHandling( ETrue, EFalse ); FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") )); return KErrNone; } @@ -374,7 +388,7 @@ iCarriageReturn = 0; iLineFeed = 0; iBackspace = 0; - iCommand = NULL; + iInput = NULL; iDecodeInfo.iFirstDecode = ETrue; iDecodeInfo.iDecodeIndex = KErrNotFound; iDecodeInfo.iExtendedIndex = KErrNotFound; @@ -383,6 +397,7 @@ iDecodeInfo.iAssignFound = EFalse; iDecodeInfo.iInQuotes = EFalse; iDecodeInfo.iSpecialFound = EFalse; + iDecodeInfo.iCmdsHandled = 0; iEditorModeInfo.iContentFound = EFalse; iCmdPusher = NULL; iEcomListen = NULL; @@ -435,19 +450,19 @@ TBool firstSearch = ETrue; for ( ;; ) { - retTemp = iAtCmdExt.GetNextSpecialCommand( iInputBuffer, firstSearch ); + // Let's borrow iLineBuffer for this purpose + retTemp = iAtCmdExt.GetNextSpecialCommand( iLineBuffer, firstSearch ); if ( retTemp != KErrNone ) { break; } - HBufC8* specialCmd = HBufC8::NewMaxLC( iInputBuffer.Length() ); - TPtr8 specialCmdPtr = specialCmd->Des(); - specialCmdPtr.Copy( iInputBuffer ); - specialCmdPtr.UpperCase(); + TInt lineLength = iLineBuffer.Length(); + HBufC8* specialCmd = HBufC8::NewMaxLC( lineLength ); + *specialCmd = iLineBuffer; iSpecials.AppendL( specialCmd ); CleanupStack::Pop( specialCmd ); } - iInputBuffer.Zero(); + iLineBuffer.Zero(); FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL() complete") )); } @@ -512,6 +527,11 @@ TBool CDunAtCmdHandler::RegenerateOkReply() { FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply()") )); + if ( iDownstream->IsDataInQueue(&iOkBuffer) ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() (in queue!) complete") )); + return iQuietOn; + } iOkBuffer.Zero(); if ( iQuietOn ) { @@ -544,6 +564,11 @@ TBool CDunAtCmdHandler::RegenerateErrorReply() { FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply()") )); + if ( iDownstream->IsDataInQueue(&iErrorBuffer) ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() (in queue!) complete") )); + return iQuietOn; + } iErrorBuffer.Zero(); if ( iQuietOn ) { @@ -634,57 +659,39 @@ // Manages partial AT command // --------------------------------------------------------------------------- // -TBool CDunAtCmdHandler::ManagePartialCommand( TDesC8& aCommand, - TBool& aNeedsCarriage ) +TBool CDunAtCmdHandler::ManagePartialCommand() { FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand()") )); - aNeedsCarriage = ETrue; - // Check length of command - if ( aCommand.Length() == 0 ) + // Check one character (or unit) based input data + if ( iInput->Length() == KDunChSetMaxCharLen ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length zero) complete") )); - return ETrue; - } - // Check one character (or unit) based input data - if ( aCommand.Length() == KDunChSetMaxCharLen ) - { - EchoCommand( aCommand ); + EchoCommand(); // Handle backspace and cancel characters - TBool found = HandleSpecialCharacters( aCommand ); + TBool found = HandleSpecialCharacters(); if ( found ) { FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (special) complete") )); return ETrue; } } - TBool endFound = EFalse; - TBool overflow = AppendCommandToInputBuffer( aCommand, endFound ); - if ( overflow ) + TBool moreNeeded = ExtractLineFromInputBuffer(); + if ( moreNeeded ) { - // Overflow occurred so return ETrue (consumed) to skip all the rest - // characters until carriage return is found - FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (overflow) complete") )); - return ETrue; + // More data is not needed with "A/" (no carriage return), check that + // special case here, otherwise continue processing + if ( !IsASlashCommand() ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (more) complete") )); + return ETrue; + } } // If something went wrong, do nothing (return consumed) - if ( iInputBuffer.Length() <= 0 ) + if ( iLineBuffer.Length() <= 0 ) { FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length) complete") )); return ETrue; } - // If "A/", no carriage return is needed, check that now - if ( IsASlashCommand() ) - { - aNeedsCarriage = EFalse; - FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (A/) complete") )); - return EFalse; - } - // For other commands and if no end, just return with consumed - if ( !endFound ) - { - FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (void) complete") )); - return ETrue; - } + // For other commands, just return with consumed FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() complete") )); return EFalse; } @@ -693,17 +700,22 @@ // Echoes a command if echo is on // --------------------------------------------------------------------------- // -TBool CDunAtCmdHandler::EchoCommand( TDesC8& aDes ) +TBool CDunAtCmdHandler::EchoCommand() { FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand()") )); - if ( aDes.Length() > KDunChSetMaxCharLen ) + if ( iInput->Length() > KDunChSetMaxCharLen ) { FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (wrong length) complete") )); return EFalse; } if ( iEchoOn ) { - iEchoBuffer.Copy( aDes ); + if ( iDownstream->IsDataInQueue(&iEchoBuffer) ) + { + FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (in queue!) complete") )); + return EFalse; + } + iEchoBuffer.Copy( *iInput ); iDownstream->NotifyDataPushRequest( &iEchoBuffer, NULL ); FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() complete") )); return ETrue; @@ -716,27 +728,27 @@ // Handles backspace and cancel characters // --------------------------------------------------------------------------- // -TBool CDunAtCmdHandler::HandleSpecialCharacters( TDesC8& aCommand ) +TBool CDunAtCmdHandler::HandleSpecialCharacters() { FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters()") )); - if ( aCommand.Length() != KDunChSetMaxCharLen ) + if ( iInput->Length() != KDunChSetMaxCharLen ) { FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (wrong length) complete") )); return EFalse; } - if ( aCommand[0] == iBackspace ) + if ( (*iInput)[0] == iBackspace ) { - TInt bufferLength = iInputBuffer.Length(); - if ( bufferLength > 0 ) + TInt lineLength = iLineBuffer.Length(); + if ( lineLength > 0 ) { - iInputBuffer.SetLength( bufferLength-1 ); + iLineBuffer.SetLength( lineLength-1 ); } FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (backspace) complete") )); return ETrue; } - if ( aCommand[0] == KDunCancel ) + if ( (*iInput)[0] == KDunCancel ) { - ResetParseBuffers(); // More processing here? + ManageEndOfCmdHandling( EFalse, EFalse ); FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (cancel) complete") )); return ETrue; } @@ -745,167 +757,381 @@ } // --------------------------------------------------------------------------- -// Appends command to parse buffer +// Extracts line from input buffer to line buffer // --------------------------------------------------------------------------- // -TBool CDunAtCmdHandler::AppendCommandToInputBuffer( TDesC8& aCommand, - TBool& aEndFound ) +TBool CDunAtCmdHandler::ExtractLineFromInputBuffer() { - FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer()") )); - aEndFound = EFalse; - TInt cmdBufIndex = 0; - TInt cmdBufLim = aCommand.Length(); - while ( cmdBufIndex < cmdBufLim ) + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer()") )); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() before (%d bytes):"), iLineBuffer.Length() )); + FTRACE(FPrintRaw(iLineBuffer) ); + // Case1: If no data in iLineBuffer and end-of-line character in iInputBuffer[start]: + // - Skip end-of-line characters, find start-of-line condition, find end-of-line character + // - If partial line found (start-of-line condition and no end-of-line character): + // - Save partial line to iLineBuffer + // - Set iEndIndex to end of iInputBuffer + // - If full line found (start-of-line condition and end-of-line character): + // - Save full line to iLineBuffer + // - Skip multiple end-of-line characters until next start-of-line + // condition or end of iInputBuffer -> save this position to iEndIndex + // Case2: If no data in iLineBuffer and non-end-of-line character in iInputBuffer[start]: + // - Find end-of-line character + // - If partial line found (no end-of-line character): + // - Save partial line to iLineBuffer + // - Set iEndIndex to end of iLineBuffer + // - If full line found (end-of-line character): + // - Save full line to iLineBuffer + // - Skip multiple end-of-line characters until next start-of-line + // condition or end of iInputBuffer -> save this position to iEndIndex + // Case3: If data in iLineBuffer and end-of-line character in iInputBuffer[start]: + // - Skip end-of-line characters + // - Keep string currently in iLineBuffer + // - Skip end-of-line characters until non-end-of-line or end of + // iInputBuffer -> save this position to iEndIndex + // Case4: If data in iLineBuffer and non-end-of-line character in iInputBuffer[start]: + // - Processed the same way as Case1, however "Skip end-of-line characters" does + // not have any effect + if ( iInput->Length() <= 0 ) { - if ( iInputBuffer.Length() == iInputBuffer.MaxLength() ) + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (wrong length) complete") )); + return ETrue; + } + TBool moreNeeded = ETrue; + TBool copyNeeded = EFalse; + TInt copyLength = KErrNotFound; + TInt lineLength = iLineBuffer.Length(); + TInt lineMaxLength = iLineBuffer.MaxLength(); + TInt freeLineSpace = lineMaxLength - lineLength; + TInt inputLength = iInput->Length(); + TInt startIndex = ( iEndIndex>=0 ) ? iEndIndex : 0; + if ( startIndex >= inputLength ) + { + iEndIndex = KErrNotFound; + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (input end) complete") )); + return ETrue; + } + // Cases here: + // Case1: If no data in iLineBuffer and end-of-line character in iInputBuffer[start] + // Case2: If no data in iLineBuffer and non-end-of-line character in iInputBuffer[start] + // Case3: If data in iLineBuffer and end-of-line character in iInputBuffer[start] + // Case4: If data in iLineBuffer and non-end-of-line character in iInputBuffer[start] + // Summary: Cases 1, 2 and 4 can be combined. Case 3 needs a separate check. + TChar character = (*iInput)[startIndex]; + TBool endOfLine = IsEndOfLine(character); + if ( lineLength>0 && endOfLine ) + { + moreNeeded = HandleSpecialBufferManagement( startIndex, + copyLength, + copyNeeded ); + } + else + { + moreNeeded = HandleGenericBufferManagement( startIndex, + copyLength, + copyNeeded ); + } + if ( copyNeeded && copyLength>0 ) + { + // Check the case copyLength does not fit to iLineBuffer + // This case should be handled by returning "more data needed" + // Also reset the iLineBuffer to ensure the handling doesn't stuck + // for rest of the commands (usability case) + if ( copyLength > freeLineSpace ) { - // 1) If output is full and end found from input - // -> reset buffers and overflow found - // 2) If output is full and end not found from input - // -> don't reset buffers and overflow found - TInt foundIndex = FindEndOfCommand( aCommand ); - if ( foundIndex >= 0 ) - { - aEndFound = ETrue; - ResetParseBuffers(); - FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (reset) complete") )); - } - FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (overflow) complete") )); + iLineBuffer.Zero(); + iEndIndex = KErrNotFound; + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() after (%d bytes):"), iLineBuffer.Length() )); + FTRACE(FPrintRaw(iLineBuffer) ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (overflow) complete") )); return ETrue; } - TChar character = aCommand[cmdBufIndex]; - if ( IsEndOfCommand(character) ) - { - aEndFound = ETrue; - iEndIndex = cmdBufIndex; - break; - } - iInputBuffer.Append( aCommand[cmdBufIndex] ); - cmdBufIndex++; + iLineBuffer.Append( &(*iInput)[startIndex], copyLength ); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() after (%d bytes):"), iLineBuffer.Length() )); + FTRACE(FPrintRaw(iLineBuffer) ); } - FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() complete") )); + if ( moreNeeded ) + { + iEndIndex = KErrNotFound; + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (more needed) complete") )); + return ETrue; + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractLineFromInputBuffer() (line found) complete") )); return EFalse; } // --------------------------------------------------------------------------- -// Handles next decoded command from input buffer +// Handles generic buffer management +// (explanation in ExtractLineFromInputBuffer()) // --------------------------------------------------------------------------- // -TBool CDunAtCmdHandler::HandleNextDecodedCommand() +TBool CDunAtCmdHandler::HandleGenericBufferManagement( TInt& aStartIndex, + TInt& aCopyLength, + TBool& aCopyNeeded ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand()") )); - if ( iHandleState != EDunStateAtCmdHandling ) + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement()") )); + TInt inputLength = iInput->Length(); + TInt currentIndex = SkipEndOfLineCharacters( aStartIndex ); + if ( currentIndex >= inputLength ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (not ready) complete") )); + // No data in iLineBuffer and only end-of-lines in new buffer + // return with "need more data" + iEndIndex = inputLength; + aCopyLength = 0; + aCopyNeeded = EFalse; + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (new end for old no data) complete") )); return ETrue; } - TBool extracted = ExtractNextDecodedCommand(); - if ( !extracted ) + // No data in iLineBuffer and non-end-of-line character found + // Try to find the first start-of-line condition + TInt lineLength = iLineBuffer.Length(); + if ( lineLength == 0 ) { - ManageEndOfCmdHandling( ETrue, ETrue, ETrue ); - FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (last) complete") )); + currentIndex = SkipSubCommandDelimiterCharacters( aStartIndex ); + if ( currentIndex >= inputLength ) + { + // No data in iLineBuffer and only end-of-lines+delimiter in new buffer + // return with "need more data" + iEndIndex = inputLength; + aCopyLength = 0; + aCopyNeeded = EFalse; + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (new end+delim for old no data) complete") )); + return ETrue; + } + } + aStartIndex = currentIndex; + // No data in iLineBuffer and other than end-of-line or delimiter character found + // Variable currentIndex is now the start of new command + // Next try to find the end of the command + TInt endIndex = FindEndOfLine( aStartIndex ); + if ( endIndex >= inputLength ) + { + // No data in iLineBuffer and start of command found without end + // return with "need more data" + iEndIndex = inputLength; + aCopyLength = inputLength - aStartIndex; + aCopyNeeded = ETrue; + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (start but no end for old no data) complete") )); return ETrue; } - // Next convert the decoded AT command to uppercase - // Don't check for case status -> let mixed cases pass - iParseInfo.iSendBuffer.Copy( iDecodeInfo.iDecodeBuffer ); - TInt maxLength = iParseInfo.iSendBuffer.MaxLength(); - TPtr8 upperDes( &iParseInfo.iSendBuffer[0], iParseInfo.iLimit, maxLength ); - upperDes.UpperCase(); - // Next always send the command to ATEXT - iCmdPusher->IssueRequest( iParseInfo.iSendBuffer ); - FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") )); + // No data in iLineBuffer and end-of-line character found + // Try to skip possible multiple end-of-line characters + currentIndex = SkipEndOfLineCharacters( endIndex ); + // Variable currentIndex is now either start of next command or end of iInput + // Note that this requires that Case 2 must skip the possible IsDelimiterCharacter()s + iEndIndex = currentIndex; + aCopyLength = endIndex - aStartIndex; + aCopyNeeded = ETrue; + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleGenericBufferManagement() (line found) complete") )); return EFalse; } // --------------------------------------------------------------------------- -// Finds the start of the next command +// Handles special buffer management +// (explanation in ExtractLineFromInputBuffer()) // --------------------------------------------------------------------------- // -TInt CDunAtCmdHandler::FindStartOfNextCommand() +TBool CDunAtCmdHandler::HandleSpecialBufferManagement( TInt aStartIndex, + TInt& aCopyLength, + TBool& aCopyNeeded ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand()") )); - // Note: here we need to avoid internal recursion when parsing the - // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the - // same upstream block. - // Skip all the extra markers except the one we already know to exist. - TInt i; - TInt startVal = iEndIndex + 1; - TInt foundIndex = KErrNotFound; - TInt count = iCommand->Length(); - for ( i=startVal; iLength(); + TInt inputLength = foundIndex; + for ( TInt i=aStartIndex; iLength(); + TInt foundIndex = inputLength; + for ( TInt i=aStartIndex; iLength(); + TInt foundIndex = inputLength; + for ( TInt i=aStartIndex; i let mixed cases pass + TInt oldLength = iParseInfo.iSendBuffer.Length(); + iParseInfo.iSendBuffer.SetLength( iParseInfo.iLimit ); + iParseInfo.iSendBuffer.UpperCase(); + iParseInfo.iSendBuffer.SetLength( oldLength ); + // Next always send the command to ATEXT + iCmdPusher->IssueRequest( iParseInfo.iSendBuffer ); + FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextSubCommand() complete") )); + return ETrue; + } + +// --------------------------------------------------------------------------- // Manages end of AT command handling // --------------------------------------------------------------------------- // -void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal, - TBool aNotifyLocal, - TBool aClearInput ) +void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyLocal, + TBool aNotifyExternal ) { FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") )); - if ( iInputBuffer.Length() > 0 ) + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (loc=%d, ext=%d)"), aNotifyLocal, aNotifyExternal )); + // If iEndIndex is (>=0 && Length(); + TBool subBlock = ( iEndIndex>=0&&iEndIndex0 && !subBlock ) { - iLastBuffer.Copy( iInputBuffer ); + // Line buffer set and no partial subblock, copy to lastbuffer + iLastBuffer.Copy( iLineBuffer ); } - ResetParseBuffers( aClearInput ); + iLineBuffer.Zero(); + iDecodeInfo.iFirstDecode = ETrue; + iDecodeInfo.iDecodeIndex = 0; + iDecodeInfo.iPrevExists = EFalse; + iParseInfo.iLimit = KErrNotFound; + iParseInfo.iSendBuffer.Zero(); + iEditorModeInfo.iContentFound = EFalse; iHandleState = EDunStateIdle; if ( aNotifyLocal ) { iCmdPusher->SetEndOfCmdLine(); } - if ( !aNotifyExternal ) + // iEndIndex must not be reset to KErrNotFound only when + // ExtractLineFromInputBuffer() found the next line + // (when moreNeeded is EFalse) + TBool resetIndex = ETrue; + if ( aNotifyExternal ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") )); - return; + TBool moreNeeded = ExtractLineFromInputBuffer(); + if ( moreNeeded ) + { + iUpstream->NotifyParserNeedsMoreData(); + } + else + { + // AppendBlockToInputBuffer() was able to fill with known end, handle next + iHandleState = EDunStateAtCmdHandling; + HandleNextSubCommand(); + resetIndex = EFalse; + } } - TInt foundIndex = FindStartOfNextCommand(); - iUpstream->NotifyAtCmdHandlingEnd( foundIndex ); + if ( resetIndex ) + { + iEndIndex = KErrNotFound; + } FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") )); } // --------------------------------------------------------------------------- -// Extracts next decoded command from input buffer to decode buffer +// Extracts next subcommand from line buffer to send buffer // --------------------------------------------------------------------------- // -TBool CDunAtCmdHandler::ExtractNextDecodedCommand( TBool aPeek ) +TBool CDunAtCmdHandler::ExtractNextSubCommand( TBool aPeek ) { - FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") )); - iParseInfo.iLimit = KErrNotFound; + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand()") )); TDunDecodeInfo oldInfo = iDecodeInfo; - iDecodeInfo.iDecodeBuffer.Zero(); - // Find start of decode command from input buffer - TInt startIndex = iDecodeInfo.iDecodeIndex; - startIndex = FindStartOfDecodedCommand( iInputBuffer, startIndex ); + iParseInfo.iLimit = KErrNotFound; + iParseInfo.iSendBuffer.Zero(); + // Find start of subcommand from line buffer + TInt startIndex = FindStartOfSubCommand(); if ( startIndex < 0 ) { RestoreOldDecodeInfo( aPeek, oldInfo ); FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") )); return EFalse; } - // Find end of decode command from input buffer + iDecodeInfo.iDecodeIndex = startIndex; TBool specialCmd = EFalse; TInt endIndex = KErrNotFound; - specialCmd = CheckSpecialCommand( startIndex, endIndex ); + specialCmd = CheckSpecialCommand( endIndex ); if ( !specialCmd ) { - FindSubCommand( startIndex, endIndex ); + FindSubCommand( endIndex ); } - if ( endIndex < startIndex ) + TInt lineLength = iLineBuffer.Length(); + TBool inStartLimits = ( startIndex >= 0 && startIndex < lineLength ) ? ETrue : EFalse; + TBool inEndLimits = ( endIndex >= 0 && endIndex < lineLength ) ? ETrue : EFalse; + if ( !inStartLimits || !inEndLimits ) { RestoreOldDecodeInfo( aPeek, oldInfo ); - FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") )); + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand() (no end) complete") )); return EFalse; } TInt cmdLength = endIndex - startIndex + 1; @@ -917,8 +1143,8 @@ // Next create a new command if ( !iDecodeInfo.iFirstDecode ) { - _LIT( KAtMsg, "AT" ); - iDecodeInfo.iDecodeBuffer.Append( KAtMsg ); + _LIT( KAtPrefix, "AT" ); + iParseInfo.iSendBuffer.Append( KAtPrefix ); if ( !specialCmd ) // Already added with CheckSpecialCommand() { iParseInfo.iLimit += 2; // Length of "AT" @@ -926,17 +1152,44 @@ // Note: The length of iDecodeBuffer is not exceeded here because "AT" // is added only for the second commands after that. } - TPtrC8 decodedCmd = iInputBuffer.Mid( startIndex, cmdLength ); - iDecodeInfo.iDecodeBuffer.Append( decodedCmd ); - // Set index for next round + iParseInfo.iSendBuffer.Append( &iLineBuffer[startIndex], cmdLength ); + // Change settings for the next decode round iDecodeInfo.iFirstDecode = EFalse; iDecodeInfo.iDecodeIndex = endIndex + 1; RestoreOldDecodeInfo( aPeek, oldInfo ); - FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() complete") )); + if ( !aPeek ) + { + iDecodeInfo.iCmdsHandled++; + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand() (handled=%d)"), iDecodeInfo.iCmdsHandled )); + } + FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextSubCommand() complete") )); return ETrue; } // --------------------------------------------------------------------------- +// Finds the start of subcommand from line buffer +// --------------------------------------------------------------------------- +// +TBool CDunAtCmdHandler::FindStartOfSubCommand() + { + FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfSubCommand()") )); + TInt i; + TInt foundIndex = KErrNotFound; + TInt lineLength = iLineBuffer.Length(); + for ( i=iDecodeInfo.iDecodeIndex; i upperBuf; + TInt atPrefixLen = 0; + TInt startIndex = iDecodeInfo.iDecodeIndex; + TInt newLength = iLineBuffer.Length() - startIndex; + TBuf8 upperBuf; if ( !iDecodeInfo.iFirstDecode ) { // For cases such as "ATM1L3DT*99#" "DT" must have "AT" - _LIT8( KATMsg, "AT" ); - upperBuf.Copy( KATMsg ); - atMsgLen = 2; // "AT" - newLength += atMsgLen; + _LIT8( KAtPrefix, "AT" ); + upperBuf.Copy( KAtPrefix ); + atPrefixLen = 2; // "AT" + newLength += atPrefixLen; } - upperBuf.Append( &iInputBuffer[aStartIndex], newLength ); + upperBuf.Append( &iLineBuffer[startIndex], newLength ); upperBuf.UpperCase(); TInt i; TInt count = iSpecials.Count(); @@ -1089,7 +1297,7 @@ if ( cmpResult == 0 ) { iParseInfo.iLimit = specialLength; - aEndIndex = (origLength-1) + aStartIndex - atMsgLen; + aEndIndex = (origLength-1) + startIndex - atPrefixLen; FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() complete") )); return ETrue; } @@ -1191,9 +1399,25 @@ { iDecodeInfo.iExtendedIndex = aEndIndex; SaveFoundCharDecodeState( aCharacter ); - FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (no border) complete") )); + FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (no border normal) complete") )); return EFalse; } + // Now suspect border found so peek the next character after the suspected + // extended character. If it is not alphabetical character, return with EFalse. + // This case is to detect the cases such as "AT+VTS={*,3000}", where '*' would + // be the start of the next command in normal cases. + TInt peekIndex = aEndIndex + 1; + TInt lineLength = iLineBuffer.Length(); + if ( peekIndex < lineLength ) + { + TChar nextCharacter = iLineBuffer[peekIndex]; + if ( !nextCharacter.IsAlpha() ) + { + SaveFoundCharDecodeState( aCharacter ); + FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (no border special) complete") )); + return EFalse; + } + } aEndIndex--; FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (border) complete") )); return ETrue; @@ -1267,21 +1491,22 @@ // Finds subcommand // --------------------------------------------------------------------------- // -TInt CDunAtCmdHandler::FindSubCommand( TInt aStartIndex, TInt& aEndIndex ) +TInt CDunAtCmdHandler::FindSubCommand( TInt& aEndIndex ) { FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand()") )); - aEndIndex = aStartIndex; + TInt startIndex = iDecodeInfo.iDecodeIndex; + aEndIndex = startIndex; TBool found = EFalse; - TInt length = iInputBuffer.Length(); + TInt lineLength = iLineBuffer.Length(); iDecodeInfo.iAssignFound = EFalse; iDecodeInfo.iInQuotes = EFalse; iDecodeInfo.iExtendedIndex = KErrNotFound; SaveNotFoundCharDecodeState(); iAtSpecialCmdHandler->ResetComparisonBuffer(); // just to be sure - for ( ; aEndIndexLength(); // Causes skipping of last '/' in ManageEndOfCmdHandling() // If "A/" command and last buffer exist, set the last buffer as the current buffer if ( iLastBuffer.Length() > 0 ) { - iInputBuffer.Copy( iLastBuffer ); + iLineBuffer.Copy( iLastBuffer ); FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (copy) complete") )); return EFalse; } - // Last buffer not set so return "ERROR" if quiet mode not on - if ( iQuietOn ) - { - FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (quiet) complete") )); - return EFalse; - } + // Last buffer not set so return "ERROR" iDownstream->NotifyDataPushRequest( &iErrorBuffer, NULL ); FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() complete") )); return ETrue; } // --------------------------------------------------------------------------- -// Resets parse buffers -// --------------------------------------------------------------------------- -// -void CDunAtCmdHandler::ResetParseBuffers( TBool aClearInput ) - { - FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers()") )); - if ( aClearInput ) - { - iInputBuffer.Zero(); - } - iDecodeInfo.iFirstDecode = ETrue; - iDecodeInfo.iDecodeIndex = 0; - iDecodeInfo.iPrevExists = EFalse; - iDecodeInfo.iDecodeBuffer.Zero(); - FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers() complete") )); - } - -// --------------------------------------------------------------------------- // Manages command mode change // --------------------------------------------------------------------------- // @@ -1585,7 +1788,7 @@ if ( !nextContentFound ) { iUpstream->NotifyEditorModeReply( aStart ); - FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") )); + FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply() complete") )); return KErrNone; } // In block mode end the block mode by sending and hope it works. @@ -1608,22 +1811,23 @@ FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (skip) complete" ) )); return iEditorModeInfo.iContentFound; } - iEditorModeInfo.iContentFound = EFalse; - TInt foundCmdIndex = KErrNotFound; - TBool nextContentFound = ExtractNextDecodedCommand( ETrue ); // peek - if ( !nextContentFound ) + // If iEndIndex is (>=0 && Length(); + TBool subBlock = ( iEndIndex>=0&&iEndIndexIsDataInQueue(&iRecvBuffer) ) + { + FTRACE(FPrint( _L("CDunAtCmdPusher::IssueRequest() (in queue!) complete") )); + return KErrGeneral; + } iStatus = KRequestPending; iAtCmdExt->HandleCommand( iStatus, - aCommand, + aInput, iRecvBuffer, iReplyLeftPckg, iReplyTypePckg ); @@ -132,6 +137,7 @@ TInt CDunAtCmdPusher::Stop() { FTRACE(FPrint( _L("CDunAtCmdPusher::Stop()") )); + SetEndOfCmdLine(); if ( iAtPushState != EDunStateAtCmdPushing ) { FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() (not ready) complete" ))); @@ -142,7 +148,6 @@ // idle eventually), cancel the actual operation in DoCancel() Cancel(); iAtPushState = EDunStateIdle; - SetEndOfCmdLine(); FTRACE(FPrint( _L("CDunAtCmdPusher::Stop() complete") )); return KErrNone; } @@ -480,8 +485,9 @@ // First check if error or stop condition detected if ( iReplyType==EReplyTypeError || iStop ) { + SetEndOfCmdLine(); + iAtPushState = EDunStateIdle; iCallback->NotifyEndOfCmdLineProcessing(); - iAtPushState = EDunStateIdle; FTRACE(FPrint( _L("CDunAtCmdPusher::NotifyDataPushComplete() (error reply) complete") )); return; } diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/plugins/src/bt/DunBtListen.cpp --- a/localconnectivityservice/dun/plugins/src/bt/DunBtListen.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/plugins/src/bt/DunBtListen.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -343,11 +343,11 @@ return KErrInUse; } aChannelNum = aListenSocket.LocalPort(); - + // We try to set the Telephony and Networking bits in our service class. If this fails we // ignore it, as it's better to carry on without it than to fail to start listening. - (void)aListenSocket.SetOpt(KBTRegisterCodService, KSolBtRFCOMM, KCoDDunServiceClass); - + aListenSocket.SetOpt(KBTRegisterCodService, KSolBtRFCOMM, KCoDDunServiceClass); + retTemp = aListenSocket.Listen( KListenQueSize ); if ( retTemp != KErrNone ) { diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/inc/DunDataPusher.h --- a/localconnectivityservice/dun/utils/inc/DunDataPusher.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/inc/DunDataPusher.h Thu Aug 19 10:46:39 2010 +0300 @@ -38,7 +38,7 @@ /** * Data to push to the stream (not copied) */ - const TDesC8 *iPushedData; + const TDesC8* iDataToPush; /** * Callback to call when data is processed by the stream @@ -127,30 +127,30 @@ * Adds event notification to queue * * @since S60 3.2 - * @param aPushedData Data to push to the stream (not copied) + * @param aDataToPush Data to push to the stream (not copied) * @param aCallback Callback to call when data is processed by the stream * @return Symbian error code on error, KErrNone otherwise */ - TInt AddToEventQueue( const TDesC8 *aPushedData, + TInt AddToEventQueue( const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ); /** * Finds an event from queue * * @since S60 5.0 - * @param aPushedData Data to push to the stream (not copied) + * @param aDataToPush Data to push to the stream (not copied) * @return Index of found event, Symbian error code otherwise */ - TInt FindEventFromQueue( const TDesC8 *aPushedData ); + TInt FindEventFromQueue( const TDesC8* aDataToPush ); /** * Stops one event in the event queue * * @since S60 5.0 - * @param aPushedData Data to push to the stream (not copied) + * @param aDataToPush Data to push to the stream (not copied) * @return Symbian error code on error, KErrNone otherwise */ - TInt StopOneEvent( const TDesC8 *aPushedData ); + TInt StopOneEvent( const TDesC8* aDataToPush ); /** * Sends queued data in round robin diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/inc/DunDownstream.h --- a/localconnectivityservice/dun/utils/inc/DunDownstream.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/inc/DunDownstream.h Thu Aug 19 10:46:39 2010 +0300 @@ -73,14 +73,23 @@ * Gets called when outside party wants to push data to the existing stream * * @since S60 5.0 - * @param aPushedData Data to push to the stream (not copied) + * @param aDataToPush Data to push to the stream (not copied) * @param aCallback Callback to call when data is processed by the stream * @return Symbian error code on error, KErrNone otherwise */ virtual TInt NotifyDataPushRequest( - const TDesC8 *aPushedData, + const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ) = 0; + /** + * Checks if data is in queue + * + * @since TB9.2 + * @param aDataToPush Data to check + * @return ETrue if data is in queue, EFalse otherwise + */ + virtual TBool IsDataInQueue( const TDesC8 *aDataToPush ) = 0; + }; /** @@ -146,14 +155,23 @@ TInt InitializeForDataPushing( MDunAtCmdHandler* aAtCmdHandler ); /** + * Checks if data is in queue + * + * @since TB9.2 + * @param aDataToPush Data to check + * @return ETrue if data is in queue, EFalse otherwise + */ + TBool IsDataInQueue( const TDesC8* aDataToPush ); + + /** * Adds data to event queue and starts sending if needed * * @since S60 5.0 - * @param aPushedData Data to push to the stream (not copied) + * @param aDataToPush Data to push to the stream (not copied) * @param aCallback Callback to call when data is processed by the stream * @return Symbian error code on error, KErrNone otherwise */ - TInt AddToQueueAndSend( const TDesC8 *aPushedData, + TInt AddToQueueAndSend( const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ); private: @@ -204,11 +222,11 @@ * Gets called when outside party wants to push data to the existing stream * * @since S60 3.2 - * @param aPushedData Data to push to the stream (not copied) + * @param aDataToPush Data to push to the stream (not copied) * @param aCallback Callback to call when data is processed by the stream * @return Symbian error code on error, KErrNone otherwise */ - TInt NotifyDataPushRequest( const TDesC8 *aPushedData, + TInt NotifyDataPushRequest( const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ); // from base class MDunCompletionReporter diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/inc/DunUpstream.h --- a/localconnectivityservice/dun/utils/inc/DunUpstream.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/inc/DunUpstream.h Thu Aug 19 10:46:39 2010 +0300 @@ -77,17 +77,7 @@ TBool iDataMode; /** - * Flag to indicate whether AT parsing is needed or not - */ - TBool iParseNeeded; - - /** - * Flag to be set when AT command handling starts - */ - TBool iHandling; - - /** - * AT Command handler. Used if iAtParseNeeded is ETrue + * AT Command handler. */ CDunAtCmdHandler* iAtCmdHandler; @@ -270,21 +260,12 @@ // from base class MDunAtCmdStatusReporter /** - * Notifies about AT command handling start + * Notifies about parser's need to get more data * - * @since S60 5.0 + * @since TB9.2 * @return None */ - void NotifyAtCmdHandlingStart(); - - /** - * Notifies about AT command handling end - * - * @since S60 5.0 - * @param aEndIndex Index to the start of next command - * @return None - */ - void NotifyAtCmdHandlingEnd( TInt aStartIndex ); + void NotifyParserNeedsMoreData(); /** * Notifies about editor mode reply diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/src/DunDataPusher.cpp --- a/localconnectivityservice/dun/utils/src/DunDataPusher.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/src/DunDataPusher.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -99,17 +99,17 @@ // Adds event notification to queue // --------------------------------------------------------------------------- // -TInt CDunDataPusher::AddToEventQueue( const TDesC8 *aPushedData, +TInt CDunDataPusher::AddToEventQueue( const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ) { FTRACE(FPrint( _L("CDunDataPusher::AddToQueue()" ))); - if ( !aPushedData || aPushedData->Length()<0 ) + if ( !aDataToPush || aDataToPush->Length()<0 ) { FTRACE(FPrint( _L("CDunDataPusher::AddToQueue() (unknown data) complete" ))); return KErrGeneral; } // Check if identical pointer to data already exists - TInt foundIndex = FindEventFromQueue( aPushedData ); + TInt foundIndex = FindEventFromQueue( aDataToPush ); if ( foundIndex >= 0 ) { FTRACE(FPrint( _L("CDunDataPusher::AddToQueue() (already exists) complete" ))); @@ -117,7 +117,7 @@ } // Unique pointer -> add to event queue TDunDataPush dataPush; - dataPush.iPushedData = aPushedData; + dataPush.iDataToPush = aDataToPush; dataPush.iCallback = aCallback; TInt retTemp = iEventQueue.Append( dataPush ); if ( retTemp != KErrNone ) @@ -125,7 +125,7 @@ FTRACE(FPrint( _L("CDunDataPusher::AddToQueue() (append failed!) complete" ))); return retTemp; } - FTRACE(FPrint( _L("CDunDataPusher::AddToQueue() complete (%d)" ), iEventQueue.Count() )); + FTRACE(FPrint( _L("CDunDataPusher::AddToQueue() complete (count=%d)" ), iEventQueue.Count() )); return KErrNone; } @@ -133,14 +133,14 @@ // Finds an event from queue // --------------------------------------------------------------------------- // -TInt CDunDataPusher::FindEventFromQueue( const TDesC8 *aPushedData ) +TInt CDunDataPusher::FindEventFromQueue( const TDesC8* aDataToPush ) { FTRACE(FPrint( _L("CDunDataPusher::FindEventFromQueue()" ))); TInt i; TInt count = iEventQueue.Count(); for ( i=0; i= 0 ) { if ( iEventIndex == foundIndex ) @@ -334,17 +334,18 @@ FTRACE(FPrint( _L("CDunDataPusher::ManageOneEvent() (buffer mismatch) complete" ))); return KErrGeneral; } - iStatus = KRequestPending; - const TDesC8 *pushedData = iEventQueue[iEventIndex].iPushedData; + const TDesC8* dataToPush = iEventQueue[iEventIndex].iDataToPush; if ( iComm ) { - iComm->Write( iStatus, *pushedData ); - FTRACE(FPrint( _L("CDunDataPusher::ManageOneEvent() RComm Write() requested" ) )); + iStatus = KRequestPending; + iComm->Write( iStatus, *dataToPush ); + FTRACE(FPrint( _L("CDunDataPusher::ManageOneEvent() RComm Write() requested (buffer=0x%08X)" ), dataToPush )); } else if ( iSocket ) { - iSocket->Send( *pushedData, 0, iStatus ); - FTRACE(FPrint( _L("CDunDataPusher::ManageOneEvent() RSocket Send() requested" ) )); + iStatus = KRequestPending; + iSocket->Send( *dataToPush, 0, iStatus ); + FTRACE(FPrint( _L("CDunDataPusher::ManageOneEvent() RSocket Send() requested (buffer=0x%08X)" ), dataToPush )); } else { @@ -385,7 +386,7 @@ // void CDunDataPusher::RunL() { - FTRACE(FPrint( _L("CDunDataPusher::RunL()" ))); + FTRACE(FPrint( _L("CDunDataPusher::RunL() (buffer=0x%08X)" ), iEventQueue[iEventIndex].iDataToPush )); TBool isError; TInt retTemp = iStatus.Int(); diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/src/DunDownstream.cpp --- a/localconnectivityservice/dun/utils/src/DunDownstream.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/src/DunDownstream.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -116,10 +116,27 @@ } // --------------------------------------------------------------------------- +// Checks if data is in queue +// --------------------------------------------------------------------------- +// +TBool CDunDownstream::IsDataInQueue( const TDesC8* aDataToPush ) + { + FTRACE(FPrint( _L("CDunDownstream::IsDataInQueue()" ) )); + if ( !iPushData.iDataPusher ) + { + FTRACE(FPrint( _L("CDunDownstream::IsDataInQueue() (iPushData.iDataPusher not initialized!) complete" ))); + return EFalse; + } + TInt foundIndex = iPushData.iDataPusher->FindEventFromQueue( aDataToPush ); + FTRACE(FPrint( _L("CDunDownstream::IsDataInQueue() complete" ) )); + return ( foundIndex >= 0 ) ? ETrue : EFalse; + } + +// --------------------------------------------------------------------------- // Adds data to event queue and starts sending if needed // --------------------------------------------------------------------------- // -TInt CDunDownstream::AddToQueueAndSend( const TDesC8 *aPushedData, +TInt CDunDownstream::AddToQueueAndSend( const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ) { FTRACE(FPrint( _L("CDunDownstream::AddToQueueAndSend()" ) )); @@ -129,7 +146,7 @@ return KErrGeneral; } // Add to event queue. If something went wrong, just return - TInt retTemp = iPushData.iDataPusher->AddToEventQueue( aPushedData, aCallback ); + TInt retTemp = iPushData.iDataPusher->AddToEventQueue( aDataToPush, aCallback ); if ( retTemp != KErrNone ) { FTRACE(FPrint( _L("CDunDownstream::AddToQueueAndSend() (ERROR) complete" ))); @@ -149,6 +166,7 @@ TInt CDunDownstream::StartStream() { FTRACE(FPrint( _L("CDunDownstream::StartStream()" ) )); + FTRACE(FPrint( _L("CDunDownstream::StartStream() (buffer=0x%08X)" ), iBufferPtr )); // Note: only start URC here. // The downstream read request is started when command mode ends. // This is done to make the data arrive in the correct order (reply vs. @@ -363,13 +381,13 @@ // Gets called when outside party wants to push data to the existing stream // --------------------------------------------------------------------------- // -TInt CDunDownstream::NotifyDataPushRequest( const TDesC8 *aPushedData, +TInt CDunDownstream::NotifyDataPushRequest( const TDesC8* aDataToPush, MDunCompletionReporter* aCallback ) { FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushRequest()" ))); // If in data mode push the reply anyway as "CONNECT" or "NO CARRIER" // reply could arrive before/after the command mode information itself. - TInt retVal = AddToQueueAndSend( aPushedData, aCallback ); + TInt retVal = AddToQueueAndSend( aDataToPush, aCallback ); FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushRequest() complete" ))); return retVal; } diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/src/DunNoteHandler.cpp --- a/localconnectivityservice/dun/utils/src/DunNoteHandler.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/src/DunNoteHandler.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "DunNoteHandler.h" #include "DunDebug.h" diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/dun/utils/src/DunUpstream.cpp --- a/localconnectivityservice/dun/utils/src/DunUpstream.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/dun/utils/src/DunUpstream.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -124,8 +124,6 @@ atCmdHandler->AddCmdModeCallback( aCallbackUp ); atCmdHandler->AddCmdModeCallback( aCallbackDown ); iParseData.iDataMode = EFalse; - iParseData.iParseNeeded = ETrue; - iParseData.iHandling = EFalse; iParseData.iAtCmdHandler = atCmdHandler; FTRACE(FPrint( _L("CDunUpstream::InitializeForAtParsing() complete" ) )); return KErrNone; @@ -245,8 +243,6 @@ iActivityData.iDataRead = EFalse; iActivityData.iNotified = EFalse; iParseData.iDataMode = EFalse; - iParseData.iParseNeeded = EFalse; - iParseData.iHandling = EFalse; iParseData.iAtCmdHandler = NULL; } @@ -323,7 +319,7 @@ { FTRACE(FPrint( _L("CDunUpstream::ProcessReadData()" ))); // The following will be transferred to Dataport - if ( iParseData.iDataMode || !iParseData.iParseNeeded ) + if ( iParseData.iDataMode ) { iOperationType = EDunOperationTypeWrite; FTRACE(FPrint( _L("CDunUpstream::ProcessReadData() (next write) complete" ))); @@ -336,14 +332,16 @@ } // The following will be transferred to parser TInt retTemp = KErrNone; - TBool partialInput = EFalse; - retTemp = iParseData.iAtCmdHandler->ParseCommand( *iBufferPtr, - partialInput ); - if ( retTemp!=KErrNone || !partialInput ) + TBool moreNeeded = EFalse; + retTemp = iParseData.iAtCmdHandler->AddDataForParsing( *iBufferPtr, + moreNeeded ); + if ( retTemp!=KErrNone || !moreNeeded ) { + // If error or no error but no more data needed, don't reissue FTRACE(FPrint( _L("CDunUpstream::ProcessReadData() (no reissue) complete" ))); return EFalse; } + // If no error and more data needed, reissue FTRACE(FPrint( _L("CDunUpstream::ProcessReadData() (reissue) complete" ))); return ETrue; } @@ -446,56 +444,14 @@ // --------------------------------------------------------------------------- // From class MDunAtCmdStatusReporter -// Notifies about AT command handling start -// --------------------------------------------------------------------------- -// -void CDunUpstream::NotifyAtCmdHandlingStart() - { - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingStart()" ))); - if ( iParseData.iHandling ) - { - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingStart() (already set!)" ))); - } - iParseData.iHandling = ETrue; - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingStart() complete" ))); - } - -// --------------------------------------------------------------------------- -// From class MDunAtCmdStatusReporter -// Notifies about AT command handling end +// Notifies about parser's need to get more data // --------------------------------------------------------------------------- // -void CDunUpstream::NotifyAtCmdHandlingEnd( TInt aStartIndex ) +void CDunUpstream::NotifyParserNeedsMoreData() { - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingEnd()" ))); - if ( !iParseData.iHandling ) - { - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingEnd() (already set!)" ))); - } - iParseData.iHandling = EFalse; - // Next check the offset to the next command inside this block - TInt length = iBufferPtr->Length(); - if ( aStartIndex < 0 ) - { - // Start of the next command not found so here we need to just reissue - // the read request and not clear the input buffer. - iParseData.iAtCmdHandler->SetEndOfCmdLine( EFalse ); - IssueRequest(); // iOperationType must be read here (don't set) - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingEnd() (not found) complete" ))); - return; - } - // Here the start of next command was found so try to directly handle that - // command using ProcessReadData() for the next subblock. - iParseData.iAtCmdHandler->SetEndOfCmdLine( ETrue ); - TInt maxLength = iBufferPtr->MaxLength(); - iBufferPtr->Set( &(*iBufferPtr)[aStartIndex], length-aStartIndex, maxLength ); - TBool reIssue = ProcessReadData(); - if ( reIssue ) - { - // Note: should come here only if something went wrong - IssueRequest(); - } - FTRACE(FPrint( _L("CDunUpstream::NotifyAtCmdHandlingEnd() complete" ))); + FTRACE(FPrint( _L("CDunUpstream::NotifyParserNeedsMoreData()" ))); + IssueRequest(); // iOperationType must be read here (don't set) + FTRACE(FPrint( _L("CDunUpstream::NotifyParserNeedsMoreData() complete" ))); } // --------------------------------------------------------------------------- diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexreceiveservices/bip/src/BIPController.cpp --- a/localconnectivityservice/obexreceiveservices/bip/src/BIPController.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexreceiveservices/bip/src/BIPController.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -293,8 +293,22 @@ if (iBTObject) { - iTotalSizeByte = iBTObject->Length(); // get size of receiving file + if(iBTTransferState == ETransferPutDiskError) + { + return KErrDiskFull; + } + + if(iBTObject->Name().Length() > KMaxFileName) + { + TRACE_INFO( _L( "[oppreceiveservice] COPPController: PutPacketIndication truncating name of file being received\t" ) ); + TRAPD(err, iBTObject->SetNameL(iBTObject->Name().Left(KMaxFileName))); + if(err != KErrNone) + { + return KErrAccessDenied; + } + } iReceivingFileName = iBTObject->Name(); // get name of receiving file + iTotalSizeByte = iBTObject->Length(); // get size of receiving file // Check that capacity is suitable as soon as possible if(!iLengthHeaderReceived && iTotalSizeByte > 0) @@ -312,14 +326,8 @@ return KErrDiskFull; } } - if(iBTObject->Name().Length() > KMaxFileName) - { - return KErrAccessDenied; - } - if(iBTTransferState == ETransferPutDiskError) - { - return KErrDiskFull; - } + + // successfully received put packet if we reached here iBTTransferState = ETransferPut; diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexreceiveservices/opp/src/oppcontroller.cpp --- a/localconnectivityservice/obexreceiveservices/opp/src/oppcontroller.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexreceiveservices/opp/src/oppcontroller.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -106,7 +106,7 @@ void COPPController::AbortIndication() { TRACE_FUNC - HandleError(ETrue); // true because explicit abort + HandleError(EFalse); // false because note about receiving failed should appear } void COPPController::HandleError(TBool aAbort) @@ -484,7 +484,7 @@ User::Leave(KErrGeneral); } - User::LeaveIfError(iFile.Open(iFs,iFullPathFilename,EFileWrite)); + User::LeaveIfError(iFile.Open(iFs,iFullPathFilename,EFileWrite|EFileShareReadersOrWriters)); TObexRFileBackedBuffer bufferdetails(*iBuf,iFile,CObexBufObject::EDoubleBuffering); TRAPD(err, iObexObject->SetDataBufL( bufferdetails) ); diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexsendservices/obexservicesendutils/src/BTServiceClient.cpp --- a/localconnectivityservice/obexsendservices/obexservicesendutils/src/BTServiceClient.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexsendservices/obexservicesendutils/src/BTServiceClient.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of "Eclipse Public License v1.0" @@ -25,12 +25,12 @@ #include "BTConnectionTimer.h" #include "BTSUDebug.h" -const TUint16 KMtuSizeReceiv = 0xFFFF; // 64kB -const TUint16 KMtuSizeTrans = 0x3000; // 12kB -const TInt KBufferSize = 0x4000; // 16kB +const TUint16 KMtuSizeReceiv = 0xFFFF; // 64kB - 1 (65535) +const TUint16 KMtuSizeTrans = 0x8000; // 32kB +const TInt KBufferSize = 0x8000; // 32kB -const TInt KBTConnectionTimeout = 20000000; // 20 seconds -const TInt KBTAbortTimeout = 2000000; // 20 seconds +const TInt KBTConnectionTimeout = 20 * 1000 * 1000; // 20 seconds +const TInt KBTAbortTimeout = 2 * 1000 * 1000; // 2 seconds // CONSTANTS @@ -403,7 +403,8 @@ FTRACE(FPrint(_L("[BTSU]\t CBTServiceClient::GetProgressStatus() completed, bytes sent %d"), iTotalBytesSent + bytesSent ) ); - return iTotalBytesSent + bytesSent; + // return iTotalBytesSent + bytesSent; + return bytesSent; } // ----------------------------------------------------------------------------- diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexserviceman/utils/inc/obexutilsentryhandler.h --- a/localconnectivityservice/obexserviceman/utils/inc/obexutilsentryhandler.h Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexserviceman/utils/inc/obexutilsentryhandler.h Thu Aug 19 10:46:39 2010 +0300 @@ -54,19 +54,7 @@ */ TInt AddEntryAttachment(const TDesC &aFilePath, CMsvAttachment* anAttachInfo, CMsvStore* aStore ); - /** - * Update an entry attachment - * @since S60 v5.0 - * @param aFilePath the absolute file path of the linked attachment file. - * @param anAttachInfo the attachment info associated with the file. - * @param aStore An interface ove the message store that is associated with a message entry. - * @return error code - */ - TInt UpdateEntryAttachment(TFileName& aFileName, - CMsvAttachment* anOldAttachInfo, - CMsvAttachment* aNewAttachInfo, - CMsvStore* aStore ); - + // from base class CActive /** @@ -97,23 +85,6 @@ */ void ConstructL(); - /** - * Add link attachment - * - * @since S60 v5.0 - */ - void DoAddEntryAttachmentL(const TDesC &aFilePath, CMsvAttachment* anAttachInfo, CMsvStore* aStore); - - - /** - * Update link attachment - * - * @since S60 v5.0 - */ - void DoUpdateEntryAttachmentL(TFileName& aFileName, - CMsvAttachment* anOldAttachInfo, - CMsvAttachment* aNewAttachInfo, - CMsvStore* aStore); private: // member data diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexserviceman/utils/src/obexutilsentryhandler.cpp --- a/localconnectivityservice/obexserviceman/utils/src/obexutilsentryhandler.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexserviceman/utils/src/obexutilsentryhandler.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -81,7 +81,8 @@ iStatus = KRequestPending; - TRAPD(error, DoAddEntryAttachmentL(aFilePath, anAttachInfo, aStore)); + TRAPD(error, aStore->AttachmentManagerL().AddLinkedAttachmentL(aFilePath,anAttachInfo, iStatus);); + if (error != KErrNone ) { //Complete request @@ -98,76 +99,6 @@ // --------------------------------------------------------------------------- -// DoAddLinkAttachmentL() -// --------------------------------------------------------------------------- -// -void CObexutilsEntryhandler::DoAddEntryAttachmentL( - const TDesC &aFilePath, - CMsvAttachment* anAttachInfo, - CMsvStore* aStore) - { - FLOG(_L("[OBEXUTILS]\t CObexutilsEntryhandler::DoAddEntryAttachmentL()")); - - aStore->AttachmentManagerL().AddLinkedAttachmentL(aFilePath,anAttachInfo, iStatus); - - //Complete request - TRequestStatus* status = &iStatus; - User::RequestComplete(status, KErrNone); - - FLOG(_L("[OBEXUTILS]\t CObexutilsEntryhandler::DoAddEntryAttachmentL() completed")); - } - -// --------------------------------------------------------------------------- -// UpdateLinkAttachment() -// --------------------------------------------------------------------------- -// -TInt CObexutilsEntryhandler::UpdateEntryAttachment( - TFileName& aFileName, - CMsvAttachment* anOldAttachInfo, - CMsvAttachment* aNewAttachInfo, - CMsvStore* aStore) - { - FLOG(_L("[OBEXUTILS]\t CObexutilsEntryhandler::UpdateEntryAttachment()")); - - iStatus = KRequestPending; - - TRAPD(error, DoUpdateEntryAttachmentL(aFileName,anOldAttachInfo, aNewAttachInfo, aStore)); - if (error != KErrNone ) - { - //Complete request - TRequestStatus* status = &iStatus; - User::RequestComplete(status, error); - } - - SetActive(); - iSyncWaiter.Start(); - - FLOG(_L("[OBEXUTILS]\t CObexutilsEntryhandler::UpdateEntryAttachment() Done")); - return iStatus.Int(); - } - -// --------------------------------------------------------------------------- -// DoUpdateEntryAttachmentL() -// --------------------------------------------------------------------------- -// -void CObexutilsEntryhandler::DoUpdateEntryAttachmentL( - TFileName& aFileName, - CMsvAttachment* anOldAttachInfo, - CMsvAttachment* aNewAttachInfo, - CMsvStore* aStore) - { - FLOG(_L("[OBEXUTILS]\t CObexutilsEntryhandler::DoUpdateEntryAttachmentL()")); - aStore->AttachmentManagerL().RemoveAttachmentL(anOldAttachInfo->Id(), iStatus); - aStore->AttachmentManagerL().AddLinkedAttachmentL(aFileName,aNewAttachInfo, iStatus); - - //Complete request - TRequestStatus* status = &iStatus; - User::RequestComplete(status, KErrNone); - - FLOG(_L("[OBEXUTILS]\t CObexutilsEntryhandler::DoUpdateEntryAttachmentL() completed")); - } - -// --------------------------------------------------------------------------- // From class CActive. // RunL() // --------------------------------------------------------------------------- diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexserviceman/utils/src/obexutilslaunchwaiter.cpp --- a/localconnectivityservice/obexserviceman/utils/src/obexutilslaunchwaiter.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexserviceman/utils/src/obexutilslaunchwaiter.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -117,19 +117,20 @@ }// EMsvFile if ( attachInfo->Type() == CMsvAttachment::EMsvLinkedFile ) - { - CAiwGenericParamList* paramList = CAiwGenericParamList::NewLC(); // 4th push - TAiwGenericParam paramSave(EGenericParamFileSaved, ETrue); - paramList->AppendL( paramSave ); - + { if ( eikEnv ) - { - iDocumentHandler = CDocumentHandler::NewL( eikEnv->Process() ); - iDocumentHandler->SetExitObserver( this ); + { RFs rfs; User::LeaveIfError( rfs.Connect() ); if ( BaflUtils::FileExists( rfs, filePath ) ) { + CAiwGenericParamList* paramList = CAiwGenericParamList::NewLC(); // 4th push + TAiwGenericParam paramSave(EGenericParamFileSaved, ETrue); + paramList->AppendL( paramSave ); + + iDocumentHandler = CDocumentHandler::NewL( eikEnv->Process() ); + iDocumentHandler->SetExitObserver( this ); + RFile64 shareableFile; TRAP( error, iDocumentHandler->OpenTempFileL(filePath,shareableFile)); if ( error == KErrNone) @@ -137,19 +138,17 @@ TRAP( error, iDocumentHandler->OpenFileEmbeddedL( shareableFile, dataType, *paramList)); } shareableFile.Close(); + CleanupStack::PopAndDestroy(); // paramList if ( error == KErrNotSupported ) - { - delete iDocumentHandler; - iDocumentHandler = NULL; - + { const TInt sortMethod = 2; // 0 = 'By name', 1 = 'By type', // 2 = 'Most recent first' and 3 = 'Largest first' TRAP (error, TObexUtilsUiLayer::LaunchFileManagerL( filePath, sortMethod, - ETrue )); // ETrue -> launch file manager in embedded mode. - isCompleteSelf = ETrue; + ETrue )); // ETrue -> launch file manager in embedded mode. } // KErrNotSupported + isCompleteSelf = ETrue; } else { @@ -172,9 +171,7 @@ } rfs.Close(); - } // eikEnv - - CleanupStack::PopAndDestroy(); // paramList + } // eikEnv } // EMsvLinkedFile diff -r 7e0ecb5b116a -r 3dcb815346df localconnectivityservice/obexserviceman/utils/src/obexutilsmessagehandler.cpp --- a/localconnectivityservice/obexserviceman/utils/src/obexutilsmessagehandler.cpp Thu Jul 15 19:38:28 2010 +0300 +++ b/localconnectivityservice/obexserviceman/utils/src/obexutilsmessagehandler.cpp Thu Aug 19 10:46:39 2010 +0300 @@ -333,19 +333,23 @@ FLOG(_L("[OBEXUTILS]\t RecogniseObjectsL() MIME check failed")); } CleanupStack::PopAndDestroy(); // lsSess + HBufC* buf16 = HBufC::NewLC(mimeType.Length()); buf16->Des().Copy(mimeType); TPtrC mimeType16(buf16->Des()); CleanupStack::PopAndDestroy(); // buf16 - CUpdateMusicCollection* updateMusicCollection = CUpdateMusicCollection::NewL() ; + CUpdateMusicCollection* updateMusicCollection = CUpdateMusicCollection::NewL(); + CleanupStack::PushL(updateMusicCollection); if (updateMusicCollection->isSupported(mimeType16)) { updateMusicCollection->addToCollectionL(aFileName); } + CleanupStack::PopAndDestroy(); // updateMusicCollection aAttachInfo->SetMimeTypeL( mimeType ); + FLOG(_L("[OBEXUTILS]\t RecogniseObjectsL() completed")); } @@ -927,7 +931,7 @@ // TUint setAttMask(0); TUint clearAttMask(0); - User::LeaveIfError(aFile.Open(fsSess,tempFullName,EFileWrite)); + User::LeaveIfError(aFile.Open(fsSess,tempFullName,EFileWrite|EFileShareReadersOrWriters)); User::LeaveIfError(aFile.SetAtt(setAttMask , clearAttMask | KEntryAttHidden)); aFile.Close(); @@ -1000,7 +1004,7 @@ FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::AddEntryToInboxL() BIO")); RFile file; - User::LeaveIfError(file.Open(fsSess,aFullName,EFileRead)); + User::LeaveIfError(file.Open(fsSess,aFullName,EFileRead|EFileShareReadersOrWriters)); TReceivedData receivedData; receivedData.bytesReceived = fileEntry.iSize; receivedData.recTime = fileEntry.iModified; @@ -1056,37 +1060,40 @@ TFileName& aFullName, CMsvEntry* aParentEntry) { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::UpdateEntryAttachmentL() ")); CDummySessionObserver* sessionObs; CMsvSession* msvSession; CreateMsvSessionLC(sessionObs, msvSession); // 1st, 2nd push - + CMsvEntry* attachEntry = msvSession->GetEntryL(((*aParentEntry)[0]).Id()); CleanupStack::PushL(attachEntry); // 3th push - + CMsvStore* store = attachEntry->EditStoreL(); CleanupStack::PushL( store ); // 4th push - + CObexutilsEntryhandler* entryHandler = CObexutilsEntryhandler::NewL(); CleanupStack::PushL(entryHandler); // 5th push // Note: // Because setFilePath() in CMsvAttachment is not implementated by Symbian yet, // we have to delete the original attachment and add another new one to fix the broken link. - // - + // // remove the old attachment first. // store->AttachmentManagerExtensionsL().RemoveAttachmentL(0); + // Create a new attachment. // + CMsvAttachment* attachInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvLinkedFile); CleanupStack::PushL(attachInfo); // 6th push // Get mime type // RecogniseObjectsL(aFullName, attachInfo); + RFs& fsSess = msvSession->FileSession(); TParse fileNameParser; @@ -1099,10 +1106,11 @@ entryHandler->AddEntryAttachment(aFullName,attachInfo, store); CleanupStack::Pop(attachInfo); // attachInfo, Pass ownership to store CleanupStack::PopAndDestroy(entryHandler); // entryHandler - FinaliseMessageL(aParentEntry, store,fileEntry, fileNameParser); + FinaliseMessageL(aParentEntry, store,fileEntry, fileNameParser); CleanupStack::PopAndDestroy(4); // store, - // attachEntry, msvSession, sessionObs + // attachEntry, msvSession, sessionObs FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::UpdateEntryAttachmentL() completed ")); + }