localconnectivityservice/dun/atext/inc/DunAtCmdHandler.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 21:03:15 +0200
changeset 0 c3e98f10fcf4
child 12 031b9cffe6e4
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* Copyright (c) 2009 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"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  AT command handler and notifier
*
*/

#ifndef C_CDUNATCMDHANDLER_H
#define C_CDUNATCMDHANDLER_H

#include <atext.h>
#include <e32base.h>
#include <atextcommon.h>
#include "DunDataPusher.h"
#include "DunAtCmdPusher.h"
#include "DunAtEcomListen.h"
#include "DunAtModeListen.h"
#include "DunAtNvramListen.h"

const TInt KDunChSetMaxCharLen = 1;          // Only ASCII supported for now
const TInt KDunOkBufLength     = 1+1+2+1+1;  // <CR>+<LF>+"OK"+<CR>+<LF>
const TInt KDunErrorBufLength  = 1+1+5+1+1;  // <CR>+<LF>+"ERROR"+<CR>+<LF>
const TInt KDunInputBufLength  = (512 + 1);  // 512 chars for command + <CR>

class CDunAtUrcHandler;
class MDunConnMon;
class MDunStreamManipulator;

/**
 *  Class used for storing information related to string conversion and parsing
 *
 *  @lib dunatext.lib
 *  @since S60 v3.2
 */
NONSHARABLE_CLASS( TDunParseInfo )
    {

public:

    /**
     * Buffer for sending
     */
    TBuf8<KDunInputBufLength> iSendBuffer;

    /**
     * Conversion limit for upper case conversion.
     * This is needed to convert the base part of special commands to upper case
     * where the part after the base part should not be converted to upper case.
     */
    TInt iLimit;

    };

/**
 *  Class used for AT command decoding related functionality
 *
 *  @lib dunatext.lib
 *  @since S60 v5.0
 */
NONSHARABLE_CLASS( TDunDecodeInfo )
    {

public:

    /**
     * Flag to indicate if first decode
     */
    TBool iFirstDecode;

    /**
     * Index in iInputBuffer for decoding to iDecodeBuffer
     */
    TInt iDecodeIndex;

    /**
     * Previous character in parsing
     */
    TChar iPrevChar;

    /**
     * Flag to indicate if previous character exists
     */
    TBool iPrevExists;

    /**
     * Buffer for parsing
     */
    TBuf8<KDunInputBufLength> iDecodeBuffer;

    };

/**
 *  Notification interface class for command mode start/end
 *
 *  @lib dunutils.lib
 *  @since S60 v5.0
 */
NONSHARABLE_CLASS( MDunCmdModeMonitor )
    {

public:

    /**
     * Notifies about command mode start
     *
     * @since S60 5.0
     * @return None
     */
    virtual void NotifyCommandModeStart() = 0;

    /**
     * Notifies about command mode end
     *
     * @since S60 5.0
     * @return None
     */
    virtual void NotifyCommandModeEnd() = 0;

    };

/**
 *  Notification interface class for status changes in AT command handling
 *
 *  @lib dunatext.lib
 *  @since S60 v5.0
 */
NONSHARABLE_CLASS( MDunAtCmdStatusReporter )
    {

public:

    /**
     * Notifies about AT command handling start
     *
     * @since S60 5.0
     * @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;

    };

/**
 *  Class for AT command handler and notifier
 *
 *  @lib dunatext.lib
 *  @since S60 v5.0
 */
NONSHARABLE_CLASS( CDunAtCmdHandler ) : public CBase,
                                        public MDunAtCmdPusher,
                                        public MDunAtEcomListen,
                                        public MDunAtModeListen
    {

public:

    /**
     * Two-phased constructor.
     * @param aUpstream Callback to upstream
     * @param aDownstream Callback to downstream
     * @param aConnectionName Connection identifier name
     * @return Instance of self
     */
	IMPORT_C static CDunAtCmdHandler* NewL(
	    MDunAtCmdStatusReporter* aUpstream,
	    MDunStreamManipulator* aDownstream,
	    const TDesC8* aConnectionName );

    /**
    * Destructor.
    */
    virtual ~CDunAtCmdHandler();

    /**
     * Resets data to initial values
     *
     * @since S60 5.0
     * @return None
     */
    IMPORT_C void ResetData();

    /**
     * Adds callback for command mode notification
     * The callback will be called when command mode starts or ends
     *
     * @since S60 5.0
     * @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
     *
     * @since S60 5.0
     * @param aCommand Command to parse
     * @param aPartialInput ETrue if partial input, EFalse otherwise
     * @return Symbian error code on error, KErrNone otherwise
     */
    IMPORT_C TInt ParseCommand( TDesC8& aCommand, TBool& aPartialInput );

    /**
     * Manages request to abort command handling
     *
     * @since S60 5.0
     * @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 );

    /**
     * Stops sending of AT command from decode buffer
     *
     * @since S60 3.2
     * @return Symbian error code on error, KErrNone otherwise
     */
    IMPORT_C TInt Stop();

    /**
     * Starts URC message handling
     *
     * @since S60 5.0
     * @return Symbian error code on error, KErrNone otherwise
     */
    IMPORT_C TInt StartUrc();

    /**
     * Stops URC message handling
     *
     * @since S60 3.2
     * @return Symbian error code on error, KErrNone otherwise
     */
    IMPORT_C TInt StopUrc();

private:

    CDunAtCmdHandler( MDunAtCmdStatusReporter* aUpstream,
                      MDunStreamManipulator* aDownstream,
                      const TDesC8* aConnectionName );

    void ConstructL();

    /**
     * Initializes this class
     *
     * @since S60 3.2
     * @return None
     */
    void Initialize();

    /**
     * Creates plugin handlers for this class
     *
     * @since S60 5.0
     * @return None
     */
    void CreatePluginHandlersL();

    /**
     * Creates the array of special commands
     *
     * @since S60 5.0
     * @return None
     */
    void CreateSpecialCommandsL();

    /**
     * Recreates special command data.
     * This is done when a plugin is installed or uninstalled.
     *
     * @since S60 5.0
     * @return Symbian error code on error, KErrNone otherwise
     */
    TInt RecreateSpecialCommands();

    /**
     * Gets default settings from RATExtCommon and sets them to RATExt
     *
     * @since S60 5.0
     * @return None
     */
    void GetAndSetDefaultSettingsL();

    /**
     * Regenerates the reply strings based on settings
     *
     * @since S60 5.0
     * @return ETrue if quiet mode, EFalse otherwise
     */
    TBool RegenerateReplyStrings();

    /**
     * Regenerates the ok reply based on settings
     *
     * @since S60 5.0
     * @return ETrue if quiet mode, EFalse otherwise
     */
    TBool RegenerateOkReply();

    /**
     * Regenerates the error reply based on settings
     *
     * @since S60 5.0
     * @return ETrue if quiet mode, EFalse otherwise
     */
    TBool RegenerateErrorReply();

    /**
     * Gets current mode
     *
     * @since S60 5.0
     * @param aMask Mask for current mode (only one supported)
     * @return New current mode
     */
    TUint GetCurrentModeL( TUint aMask );

    /**
     * Instantiates one URC message handling class instance and adds it to
     * the URC message handler array
     *
     * @since S60 3.2
     * @return None
     */
    CDunAtUrcHandler* AddOneUrcHandlerL();

    /**
     * Deletes all instantiated URC message handlers
     *
     * @since S60 5.0
     * @return None
     */
    void DeletePluginHandlers();

    /**
     * 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
     */
    TBool ManagePartialCommand( TDesC8& aCommand,
                                TBool& aNeedsCarriage );

    /**
     * Echoes a command if echo is on
     *
     * @since S60 5.0
     * @param aDes String descriptor
     * @return ETrue if echo push started, EFalse otherwise
     */
    TBool EchoCommand( TDesC8& aDes );

    /**
     * Handles backspace and cancel characters
     *
     * @since S60 5.0
     * @param aCommand Command to process
     * @return ETrue if special character found, EFalse otherwise
     */
    TBool HandleSpecialCharacters( TDesC8& aCommand );

    /**
     * Appends command to input buffer
     *
     * @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
     */
    TBool AppendCommandToInputBuffer( TDesC8& aCommand, TBool& aEndFound );

    /**
     * Handles next decoded command from input buffer
     *
     * @since S60 5.0
     * @return ETrue if last command decoded, EFalse otherwise
     */
    TBool HandleNextDecodedCommand();

    /**
     * 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
     * ETrue.
     *
     * @since S60 5.0
     * @param aPeek Peek for the next command if ETrue, EFalse otherwise
     * @param aOldInfo Old information to restore when aPeek is ETrue
     * @return None
     */
    void RestoreOldDecodeInfo( TBool aPeek, TDunDecodeInfo& aOldInfo );

    /**
     * Finds end of an AT command
     *
     * @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
     * @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
     * @pram aExtended ETrue if extended command, EFalse otherwise
     * @return Index if found, KErrNotFound otherwise
     */
    TInt FindStartOfDecodedCommand( TDesC8& aDes,
                                    TInt aStartIndex,
                                    TBool& aExtended );

    /**
     * Checks if character is delimiter character
     *
     * @since S60 5.0
     * @param aCharacter Character to test
     * @return ETrue if delimiter character, EFalse otherwise
     */
    TBool IsDelimiterCharacter( TChar aCharacter );

    /**
     * Checks if character is of extended group
     *
     * @since S60 5.0
     * @param aCharacter Character to test
     * @return ETrue if extended character, EFalse otherwise
     */
    TBool IsExtendedCharacter( TChar aCharacter );

    /**
     * Checks extended command
     *
     * @since S60 5.0
     * @param aStartIndex Start index (doesn't change)
     * @param aEndIndex End index (changes)
     * @return ETrue if end of extended found, EFalse otherwise
     */
    TBool CheckExtendedCommand( TInt aStartIndex, TInt& aEndIndex );

    /**
     * Checks special command
     *
     * @since S60 5.0
     * @param aStartIndex Start index (doesn't change)
     * @param aEndIndex End index (changes)
     * @return Symbian error code on error, KErrNone otherwise
     */
    TBool CheckSpecialCommand( TInt aStartIndex,
                               TInt& aEndIndex );

    /**
     * Checks basic command
     *
     * @since S60 5.0
     * @param aStartIndex Start index (doesn't change)
     * @param aEndIndex End index (changes)
     * @param aACmdFound ETrue if one character "A" command found,
     *                   EFalse otherwise
     * @return Symbian error code on error, KErrNone otherwise
     */
    TInt CheckBasicCommand( TInt aStartIndex,
                            TInt& aEndIndex,
                            TBool& aOneCharCmd );

    /**
     * Check if any one character command
     *
     * @since S60 5.0
     * @param aStartIndex Start index (doesn't change)
     * @return ETrue if any one character command, EFalse otherwise
     */
    TBool IsOneCharacterCommand( TInt aStartIndex );

    /**
     * Check if one character "A" command
     *
     * @since S60 5.0
     * @param aStartIndex Start index (doesn't change)
     * @return ETrue if one character "A" command, EFalse otherwise
     */
    TBool IsOneCharacterACommand( TInt aStartIndex );

    /**
     * Check if "A/" command
     *
     * @since S60 5.0
     * @return ETrue if "A/" command, EFalse otherwise
     */
    TBool IsASlashCommand();

    /**
     * Handles "A/" command
     *
     * @since S60 5.0
     * @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
     * @param aMode Mode to manage
     * @return ETrue if command mode change detected, EFalse otherwise
     */
    TBool ManageCommandModeChange( TUint aMode );

    /**
     * Reports command mode start/end change
     *
     * @since S60 3.2
     * @param aStart Command mode start if ETrue, end otherwise
     * @return None
     */
    void ReportCommandModeChange( TBool aStart );

    /**
     * Manages echo mode change
     *
     * @since S60 5.0
     * @param aMode Mode to manage
     * @return ETrue if echo mode change detected, EFalse otherwise
     */
    TBool ManageEchoModeChange( TUint aMode );

    /**
     * Manages quiet mode change
     *
     * @since S60 5.0
     * @param aMode Mode to manage
     * @return ETrue if quiet mode change detected, EFalse otherwise
     */
    TBool ManageQuietModeChange( TUint aMode );

    /**
     * Manages verbose mode change
     *
     * @since S60 5.0
     * @param aMode Mode to manage
     * @return ETrue if verbose mode change detected, EFalse otherwise
     */
    TBool ManageVerboseModeChange( TUint aMode );

    /**
     * Manages character change
     *
     * @since S60 5.0
     * @param aMode Mode to manage
     * @return None
     */
    void ManageCharacterChange( TUint aMode );

// from base class MDunAtCmdPusher

    /**
     * From MDunAtCmdPusher.
     * Notifies about end of AT command processing.
     * This is after all reply data for an AT command is multiplexed to the
     * downstream.
     *
     * @since S60 5.0
     * @return None
     */
    TInt NotifyEndOfProcessing( TInt aError );

    /**
     * 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
     */
    TInt NotifyEndOfCmdLineProcessing();

    /**
     * Notifies about request to peek for the next command
     *
     * @since S60 5.0
     * @return ETrue if next command exists, EFalse otherwise
     */
    TBool NotifyNextCommandPeekRequest();

// from base class MDunAtEcomListen

    /**
     * From MDunAtEcomListen.
     * Notifies about new plugin installation
     *
     * @since S60 5.0
     * @return None
     */
    TInt NotifyPluginInstallation( TUid& aPluginUid );

    /**
     * From MDunAtEcomListen.
     * Notifies about existing plugin uninstallation
     *
     * @since S60 5.0
     * @return None
     */
    TInt NotifyPluginUninstallation( TUid& aPluginUid );

// from base class MDunAtModeListen

    /**
     * From MDunAtModeListen.
     * Gets called on mode status change
     *
     * @since S60 5.0
     * @param aMode Mode to manage
     * @return Symbian error code on error, KErrNone otherwise
     */
    TInt NotifyModeStatusChange( TUint aMode );

private:  // data

    /**
     * Callback to call when AT command handling status changes
     * Not own.
     */
    MDunAtCmdStatusReporter* iUpstream;

    /**
     * Callback to call when data to push
     * Not own.
     */
    MDunStreamManipulator* iDownstream;

    /**
     * Callback(s) to call when command mode starts or ends
     * Usually two needed: one for upstream and second for downstream
     */
    RPointerArray<MDunCmdModeMonitor> iCmdCallbacks;

    /**
     * Connection identifier name
     */
    const TDesC8* iConnectionName;

    /**
     * Current state of AT command handling: active or inactive
     */
    TDunState iHandleState;

    /**
     * Character for carriage return
     */
    TInt8 iCarriageReturn;

    /**
     * Character for line feed
     */
    TInt8 iLineFeed;

    /**
     * Character for backspace
     */
    TInt8 iBackspace;

    /**
     * Current command to ParseCommand()
     * Not own.
     */
    TDesC8* iCommand;

    /**
     * Special commands for parsing
     */
    RPointerArray<HBufC8> iSpecials;

    /**
     * Buffer for character echoing
     */
    TBuf8<KDunChSetMaxCharLen> iEchoBuffer;

    /**
     * Buffer for ok reply
     */
    TBuf8<KDunOkBufLength> iOkBuffer;

    /**
     * Buffer for error reply
     */
    TBuf8<KDunErrorBufLength> iErrorBuffer;

    /**
     * Buffer for AT command input
     */
    TBuf8<KDunInputBufLength> iInputBuffer;

    /**
     * Buffer for last AT command input (for "A/")
     */
    TBuf8<KDunInputBufLength> iLastBuffer;

    /**
     * AT command decoding related information
     */
    TDunDecodeInfo iDecodeInfo;

    /**
     * Information for parsing
     */
    TDunParseInfo iParseInfo;

    /**
     * AT command reply pusher
     * Own.
     */
    CDunAtCmdPusher* iCmdPusher;

    /**
     * URC message handlers
     * Own.
     */
    RPointerArray<CDunAtUrcHandler> iUrcHandlers;

    /**
     * ECOM plugin interface status change listener
     * Own.
     */
    CDunAtEcomListen* iEcomListen;

    /**
     * Modem mode status change listener
     * Own.
     */
    CDunAtModeListen* iModeListen;

    /**
     * NVRAM status change listener
     * Own.
     */
    CDunAtNvramListen* iNvramListen;

    /**
     * Flag to mark command mode start/end
     */
    TBool iDataMode;

    /**
     * Flag to be set on if echo on
     */
    TBool iEchoOn;

    /**
     * Flag to be set on if quiet mode on
     */
    TBool iQuietOn;

    /**
     * Flag to be set on if verbose mode on
     */
    TBool iVerboseOn;

    /**
     * End index for command delimiter
     */
    TInt iEndIndex;

    /**
     * AT command extension
     */
    RATExt iAtCmdExt;

    /**
     * AT command extension to common functionality
     */
    RATExtCommon iAtCmdExtCommon;

    };

#endif  // C_CDUNATCMDHANDLER_H