atcommands/modematplugin/src/modematplugin.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 09 Jun 2010 09:52:54 +0300
branchRCL_3
changeset 35 95674584745d
parent 13 b6f55cd40afd
child 57 5ebadcda06cb
permissions -rw-r--r--
Revision: 201021 Kit: 2010123

/*
* 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:  Main handler for incoming requests
*
*/


#include "modematplugin.h"
#include "atcopscmd.h"
#include "debug.h"

const TInt KErrorReplyLength = 9;  // CR+LF+"ERROR"+CR+LF

// ---------------------------------------------------------------------------
// Two-phased constructor.
// ---------------------------------------------------------------------------
//
CModemAtPlugin* CModemAtPlugin::NewL()
    {
    CModemAtPlugin* self = new (ELeave) CModemAtPlugin();
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

// ---------------------------------------------------------------------------
// Destructor.
// ---------------------------------------------------------------------------
//
CModemAtPlugin::~CModemAtPlugin()
	{
    TRACE_FUNC_ENTRY
	iHandlers.ResetAndDestroy();
	iHandlers.Close();
    iReplyBuffer.Close();
    TRACE_FUNC_EXIT
	}

// ---------------------------------------------------------------------------
// CModemAtPlugin::CModemAtPlugin
// ---------------------------------------------------------------------------
//
CModemAtPlugin::CModemAtPlugin() : CATExtPluginBase()
    {
    TRACE_FUNC_ENTRY
    iHandler = NULL;
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// CModemAtPlugin::ConstructL
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::ConstructL()
    {
    TRACE_FUNC_ENTRY
    CATCommandHandlerBase* handler = NULL;
    handler = CATCOPSCmd::NewL( this );
    CleanupStack::PushL( handler );
    iHandlers.AppendL( handler );
    CleanupStack::Pop( handler );
    TRACE_FUNC_EXIT
   	}

// ---------------------------------------------------------------------------
// Reports connection identifier name to the extension plugin.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::ReportConnectionName( const TDesC8& /*aName*/ )
    {
    TRACE_FUNC_ENTRY
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Reports the support status of an AT command. This is a synchronous API.
// ---------------------------------------------------------------------------
//
TBool CModemAtPlugin::IsCommandSupported( const TDesC8& aCmd )
    {
    TRACE_FUNC_ENTRY
    TInt i;
    TInt count = iHandlers.Count();
    for ( i=0; i<count; i++ )
        {
        CATCommandHandlerBase* handler = iHandlers[i]; 
        TBool supported = handler->IsCommandSupported( aCmd );
        if ( supported )
            {
            iHandler = handler;
            TRACE_FUNC_EXIT
            return ETrue;
            }
        }
    iHandler = NULL;
    TRACE_FUNC_EXIT
    return EFalse;
    }

// ---------------------------------------------------------------------------
// Handles an AT command. Cancelling of the pending request is done by
// HandleCommandCancel(). The implementation in the extension plugin should
// be asynchronous.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::HandleCommand( const TDesC8& aCmd,
                                     RBuf8& aReply,
                                     TBool aReplyNeeded )
	{
	TRACE_FUNC_ENTRY
	if ( iHandler )
	    {
        iHcCmd = &aCmd;
        iHcReply = &aReply;
	    iHandler->HandleCommand( aCmd, aReply, aReplyNeeded );
	    }
	TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Cancels a pending HandleCommand request.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::HandleCommandCancel()
    {
    TRACE_FUNC_ENTRY
	if ( iHandler )
	    {
	    iHandler->HandleCommandCancel();
	    }
	TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Next reply part's length.
// The value must be equal or less than KDefaultCmdBufLength.
// When the reply from this method is zero, ATEXT stops calling
// GetNextPartOfReply().
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::NextReplyPartLength()
    {
    TRACE_FUNC_ENTRY
    if ( iReplyBuffer.Length() < KDefaultCmdBufLength )
        {
        TRACE_FUNC_EXIT
        return iReplyBuffer.Length();
        }
    TRACE_FUNC_EXIT
    return KDefaultCmdBufLength;
    }

// ---------------------------------------------------------------------------
// Gets the next part of reply initially set by HandleCommandComplete().
// Length of aNextReply must be equal or less than KDefaultCmdBufLength.
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::GetNextPartOfReply( RBuf8& aNextReply )
    {
    TRACE_FUNC_ENTRY
    TInt retVal = CreatePartOfReply( aNextReply );
    TRACE_FUNC_EXIT
    return retVal;
    }

// ---------------------------------------------------------------------------
// Receives unsolicited results. Cancelling of the pending request is done by
// by ReceiveUnsolicitedResultCancel(). The implementation in the extension
// plugin should be asynchronous.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::ReceiveUnsolicitedResult()
    {
    TRACE_FUNC_ENTRY
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Cancels a pending ReceiveUnsolicitedResult request.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::ReceiveUnsolicitedResultCancel()
    {
    TRACE_FUNC_ENTRY
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Reports NVRAM status change to the plugins.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::ReportNvramStatusChange( const TDesC8& /*aNvram*/ )
    {
    TRACE_FUNC_ENTRY
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Reports about external handle command error condition.
// This is for cases when for example DUN decided the reply contained an
// error condition but the plugin is still handling the command internally.
// Example: in command line "AT+TEST;ATDT1234" was given. "AT+TEST" returns
// "OK" and "ATDT" returns "CONNECT". Because "OK" and "CONNECT" are
// different reply types the condition is "ERROR" and DUN ends processing.
// This solution keeps the pointer to the last AT command handling plugin
// inside ATEXT and calls this function there to report the error.
// It is to be noted that HandleCommandCancel() is not sufficient to stop
// the processing as the command handling has already finished.
// ---------------------------------------------------------------------------
//
void CModemAtPlugin::ReportExternalHandleCommandError()
    {
    TRACE_FUNC_ENTRY
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------------------------
// Creates part of reply from the global reply buffer to the destination
// buffer. Used with APIs which need the next part of reply in multipart reply
// requests.
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::CreatePartOfReply( RBuf8& aDstBuffer )
    {
    TRACE_FUNC_ENTRY
    if ( iReplyBuffer.Length() <= 0 )
        {
        TRACE_FUNC_EXIT
        return KErrGeneral;
        }
    TInt partLength = NextReplyPartLength();
    if ( iReplyBuffer.Length() < partLength )
        {
        TRACE_FUNC_EXIT
        return KErrNotFound;
        }
    aDstBuffer.Create( iReplyBuffer, partLength );
    iReplyBuffer.Delete( 0, partLength );
    if ( iReplyBuffer.Length() == 0 )
        {
        iReplyBuffer.Close();
        }
    TRACE_FUNC_EXIT
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// Creates an AT command reply based on the reply type and completes the
// request to ATEXT. Uses iReplyBuffer for reply storage.
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::CreateReplyAndComplete( TATExtensionReplyType aReplyType,
                                              const TDesC8& aSrcBuffer,
                                              TInt aError )
    {
    TRACE_FUNC_ENTRY
    iReplyBuffer.Close();
    if ( aError != KErrNone )
        {
        HandleCommandCompleted( aError, EReplyTypeUndefined );
        iHcCmd = NULL;
        iHcReply = NULL;
        TRACE_FUNC_EXIT
        return KErrNone;
        }
    if ( !iHcReply )
        {
        TRACE_FUNC_EXIT
        return KErrGeneral;
        }
    switch ( aReplyType )
        {
        case EReplyTypeOther:
            iReplyBuffer.Create( aSrcBuffer );
            break;
        case EReplyTypeOk:
            CreateOkOrErrorReply( iReplyBuffer, ETrue );
            break;
        case EReplyTypeError:
            CreateOkOrErrorReply( iReplyBuffer, EFalse );
            break;
        default:
            TRACE_FUNC_EXIT
            return KErrGeneral;
        }
    CreatePartOfReply( *iHcReply );
    HandleCommandCompleted( KErrNone, aReplyType );
    iHcCmd = NULL;
    iHcReply = NULL;
    TRACE_FUNC_EXIT
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// Creates a buffer for "OK" or "ERROR" reply based on the line settings
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::CreateOkOrErrorReply( RBuf8& aReplyBuffer,
                                            TBool aOkReply )
    {
    TRACE_FUNC_ENTRY
    if ( iQuietMode )
        {
        TRACE_FUNC_EXIT
        return iReplyBuffer.Create( KNullDesC8 );
        }
    _LIT8( KErrorReplyVerbose, "ERROR" );
    _LIT8( KOkReplyVerbose,    "OK" );
    _LIT8( KErrorReplyNumeric, "4" );
    _LIT8( KOkReplyNumeric,    "0" );
    TBuf8<KErrorReplyLength> replyBuffer;
    if ( iVerboseMode )
        {
        replyBuffer.Append( iCarriageReturn );
        replyBuffer.Append( iLineFeed );
        if ( aOkReply )
            {
            replyBuffer.Append( KOkReplyVerbose );
            }
        else
            {
            replyBuffer.Append( KErrorReplyVerbose );
            }
        replyBuffer.Append( iCarriageReturn );
        replyBuffer.Append( iLineFeed );
        }
    else
        {
        if ( aOkReply )
            {
            replyBuffer.Append( KOkReplyNumeric );
            }
        else
            {
            replyBuffer.Append( KErrorReplyNumeric );
            }
        replyBuffer.Append( iCarriageReturn );
        }
    TInt retVal = aReplyBuffer.Create( replyBuffer );
    TRACE_FUNC_EXIT
    return retVal;
    }

// ---------------------------------------------------------------------------
// From MLcCustomPlugin.
// Returns the array of supported commands
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::GetSupportedCommands( RPointerArray<HBufC8>& aCmds )
    {
    TRACE_FUNC_ENTRY
    // Force superclass call here:
    TInt retVal = CATExtPluginBase::GetSupportedCommands( aCmds );
    TRACE_FUNC_EXIT
    return retVal;
    }

// ---------------------------------------------------------------------------
// From MLcCustomPlugin.
// Returns plugin's character value settings (from CATExtPluginBase)
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::GetCharacterValue( TCharacterTypes aCharType,
                                         TChar& aChar )
    {
    TRACE_FUNC_ENTRY
    TInt retVal = KErrNone;
    switch ( aCharType )
        {
        case ECharTypeCR:
            aChar = iCarriageReturn;
            break;
        case ECharTypeLF:
            aChar = iLineFeed;
            break;
        case ECharTypeBS:
            aChar = iBackspace;
            break;
        default:
            retVal = KErrNotFound;
            break;
        }
    TRACE_FUNC_EXIT
    return retVal;
    }

// ---------------------------------------------------------------------------
// From MLcCustomPlugin.
// Returns plugin's mode value settings (from CATExtPluginBase)
// ---------------------------------------------------------------------------
//
TInt CModemAtPlugin::GetModeValue( TModeTypes aModeType, TBool& aMode )
    {
    TRACE_FUNC_ENTRY
    TInt retVal = KErrNone;
    switch ( aModeType )
        {
        case EModeTypeQuiet:
            aMode = iQuietMode;
            break;
        case EModeTypeVerbose:
            aMode = iVerboseMode;
            break;
        default:
            retVal = KErrNotFound;
            break;
        }
    TRACE_FUNC_EXIT
    return retVal;
    }