cbsatplugin/atmisccmdplugin/src/atmisccmdplugin.cpp
branchRCL_3
changeset 16 b23265fb36da
child 21 53b7818cd282
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbsatplugin/atmisccmdplugin/src/atmisccmdplugin.cpp	Tue Apr 27 16:49:44 2010 +0300
@@ -0,0 +1,529 @@
+/*
+* Copyright (c) 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"
+* 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 "atmisccmdplugin.h"
+
+#include "clckcommandhandler.h"
+#include "cpwdcommandhandler.h"
+#include "cpincommandhandler.h"
+#include "cusdcommandhandler.h"
+#include "cnumcommandhandler.h"
+#include "cfuncommandhandler.h"
+#include "cbccommandhandler.h"
+
+#include "atmisccmdpluginconsts.h"
+#include "debug.h"
+
+#include <EXTERROR.H>           // Additional RMobilePhone error code
+
+
+// +CME error code
+_LIT8(KCMEIncorrectPassword, "+CME: 16\r\n"); // Incorrect password.\r\n
+_LIT8(KCMEPUKRequired, "+CME: 12\r\n"); // PUK required.\r\n
+_LIT8(KCMENotAllowed, "+CME: 3\r\n"); // Operation not allowed.\r\n
+_LIT8(KCMEPhoneError, "+CME: 0\r\n"); // Phone failure.\r\n
+_LIT8(KCMEPhoneUnknown, "+CME: 100\r\n"); // unknown error
+
+const TInt KErrorReplyLength = 9;  // CR+LF+"ERROR"+CR+LF
+
+CATMiscCmdPlugin* CATMiscCmdPlugin::NewL()
+    {
+    CATMiscCmdPlugin* self = new (ELeave) CATMiscCmdPlugin();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CATMiscCmdPlugin::~CATMiscCmdPlugin()
+	{
+    iReplyBuffer.Close();
+    
+    delete iCLCKHandler;
+    delete iCPWDHandler;
+    delete iCPINHandler;
+    delete iCUSDHandler;
+    delete iCNUMHandler;
+    delete iCFUNHandler;
+    delete iCBCHandler;
+    
+    iPhone.Close();
+    iTelServer.Close();
+	}
+
+CATMiscCmdPlugin::CATMiscCmdPlugin() : 
+    CATExtPluginBase()
+    {
+    }
+
+void CATMiscCmdPlugin::ConstructL()
+    {
+    TRACE_FUNC_ENTRY
+    ConnectToEtelL(iTelServer, iPhone);
+    
+    iCLCKHandler = CCLCKCommandHandler::NewL(this, iCommandParser, iPhone);
+    iCPWDHandler = CCPWDCommandHandler::NewL(this, iCommandParser, iPhone);
+    iCUSDHandler = CCUSDCommandHandler::NewL(this, iCommandParser, iPhone);
+    iCPINHandler = CCPINCommandHandler::NewL(this, iCommandParser, iPhone);
+    iCNUMHandler = CCNUMCommandHandler::NewL(this, iCommandParser, iPhone, iTelServer);
+    iCFUNHandler = CCFUNCommandHandler::NewL(this, iCommandParser, iPhone);
+    iCBCHandler = CCBCCommandHandler::NewL(this, iCommandParser, iPhone);
+    TRACE_FUNC_EXIT
+   	}
+
+/**
+ * @see CATExtPluginBase::ReportConnectionName
+ */
+void CATMiscCmdPlugin::ReportConnectionName( const TDesC8& /*aName*/ )
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+/**
+ * @see CATExtPluginBase::IsCommandSupported
+ */
+TBool CATMiscCmdPlugin::IsCommandSupported( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+    iHcCmd = NULL;
+    iHcReply = NULL;
+    iCurrentHandler = NULL;
+    TBool supported = ETrue;
+    
+    Trace(KDebugPrintS, "aCmd: ", &aCmd);
+    
+    iCommandParser.ParseAtCommand(aCmd);
+
+    Trace(KDebugPrintD, "Command: ", iCommandParser.Command());
+    // TODO: check if the type is supported?
+    // iCommandParser.CommandHandlerType() != TAtCommandParser::ECmdHandlerTypeUndefined
+    switch (iCommandParser.Command())
+        {
+        case (TAtCommandParser::ECmdAtClck):
+            {
+            iCurrentHandler = iCLCKHandler;
+            break;
+            }
+        case (TAtCommandParser::ECmdAtCpwd):
+            {
+            iCurrentHandler = iCPWDHandler;
+            break;
+            }
+        case (TAtCommandParser::ECmdAtCpin):
+            {
+            iCurrentHandler = iCPINHandler;
+            break;
+            }
+        case (TAtCommandParser::ECmdAtCusd):
+            {
+            iCurrentHandler = iCUSDHandler;
+            break;
+            }   
+        case (TAtCommandParser::ECmdAtCnum):
+            {
+            iCurrentHandler = iCNUMHandler;
+            break;
+            }
+        case (TAtCommandParser::ECmdAtCfun):
+            {
+            iCurrentHandler = iCFUNHandler;
+            break;
+            }
+        case (TAtCommandParser::ECmdAtCbc):
+            {
+            iCurrentHandler = iCBCHandler;
+            break;
+            }
+        case (TAtCommandParser::EUnknown):
+        default:
+            {
+            supported = EFalse;
+            break;
+            }
+        }
+    Trace(KDebugPrintD, "supported: ", supported);
+    TRACE_FUNC_EXIT
+    return supported;
+	}
+
+/**
+ * @see CATExtPluginBase::HandleCommand
+ */
+void CATMiscCmdPlugin::HandleCommand( const TDesC8& aCmd,
+                                     RBuf8& aReply,
+                                     TBool aReplyNeeded )
+	{
+	TRACE_FUNC_ENTRY
+	
+	if (iCurrentHandler != NULL)
+	    {
+	    iHcCmd = &aCmd;
+	    iHcReply = &aReply;
+	    iCurrentHandler->HandleCommand( aCmd, aReply, aReplyNeeded );
+	    }
+	TRACE_FUNC_EXIT
+    }
+
+/**
+ * @see CATExtPluginBase::HandleCommandCancel
+ */
+void CATMiscCmdPlugin::HandleCommandCancel()
+    {
+    TRACE_FUNC_ENTRY
+    if (iCurrentHandler != NULL)
+	    {
+	    iCurrentHandler->HandleCommandCancel();
+	    }
+	TRACE_FUNC_EXIT
+    }
+
+/**
+ * @see CATExtPluginBase::NextReplyPartLength
+ */
+TInt CATMiscCmdPlugin::NextReplyPartLength()
+    {
+    TRACE_FUNC_ENTRY
+    TInt length = iReplyBuffer.Length();
+    if ( length >= KDefaultCmdBufLength )
+        {
+        length = KDefaultCmdBufLength;
+        }
+    TRACE_FUNC_EXIT
+    return length;
+    }
+
+/**
+ * @see CATExtPluginBase::GetNextPartOfReply
+ */
+TInt CATMiscCmdPlugin::GetNextPartOfReply( RBuf8& aNextReply )
+    {
+    TRACE_FUNC_ENTRY
+    TInt retVal = CreatePartOfReply( aNextReply );
+    TRACE_FUNC_EXIT
+    return retVal;
+    }
+
+/**
+ * @see CATExtPluginBase::ReceiveUnsolicitedResult
+ */
+void CATMiscCmdPlugin::ReceiveUnsolicitedResult()
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+/**
+ * @see CATExtPluginBase::ReceiveUnsolicitedResultCancel
+ */
+void CATMiscCmdPlugin::ReceiveUnsolicitedResultCancel()
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+/**
+ * @see CATExtPluginBase::ReportNvramStatusChange
+ */
+void CATMiscCmdPlugin::ReportNvramStatusChange( const TDesC8& /*aNvram*/ )
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+/**
+ * @see CATExtPluginBase::ReportExternalHandleCommandError
+ */
+void CATMiscCmdPlugin::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.
+ *
+ * @param aBuffer Destination buffer; the next part of reply is stored to
+ *                   this buffer.
+ * @return None
+ */
+TInt CATMiscCmdPlugin::CreatePartOfReply( RBuf8& aBuffer )
+    {
+    TRACE_FUNC_ENTRY
+    TInt ret = KErrNone;
+    TInt partLength;
+    if ( iReplyBuffer.Length() <= 0 )
+        {
+        ret = KErrGeneral;
+        }
+    else
+        {
+        partLength = NextReplyPartLength();
+        if ( iReplyBuffer.Length() < partLength )
+            {
+            ret =  KErrNotFound;
+            }
+        }
+    Trace(KDebugPrintD, "ret: ", ret);
+    if (ret == KErrNone)
+        {
+        aBuffer.Create( iReplyBuffer, partLength );
+        iReplyBuffer.Delete( 0, partLength );
+        if ( iReplyBuffer.Length() == 0 )
+            {
+            iReplyBuffer.Close();
+            }
+        }
+
+    TRACE_FUNC_EXIT
+    return ret;
+    }
+
+/**
+ * @see MATMiscCmdPlugin::CreateReplyAndComplete
+ */
+TInt CATMiscCmdPlugin::CreateReplyAndComplete( TATExtensionReplyType aReplyType,
+                                              const TDesC8& aSrcBuffer,
+											  TInt aError )
+    {
+    TRACE_FUNC_ENTRY
+    iReplyBuffer.Close();
+    Trace(KDebugPrintD, "aError: ", aError);
+    if ( aError != KErrNone )
+        {
+        HandleCommandCompleted( aError, EReplyTypeUndefined );
+        iHcCmd = NULL;
+        iHcReply = NULL;
+        iCurrentHandler = NULL;
+        TRACE_FUNC_EXIT
+        return KErrNone;
+        }
+    
+    Trace(KDebugPrintS, "iHcReply: ", &iHcReply);
+    if (iHcReply == NULL)
+        {
+        TRACE_FUNC_EXIT
+        return KErrGeneral;
+        }
+    
+    Trace(KDebugPrintD, "iQuietMode: ", iQuietMode);
+    if ( iQuietMode )
+        {
+        iReplyBuffer.Create( KNullDesC8 );
+        }
+    else
+        {
+        iReplyBuffer.Create( aSrcBuffer );
+        }
+    
+    Trace(KDebugPrintD, "aReplyType: ", aReplyType);
+    switch ( aReplyType )
+        {
+        case EReplyTypeOther:
+            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;
+    iCurrentHandler = NULL;
+    TRACE_FUNC_EXIT
+    return KErrNone;
+    }
+
+/**
+ * @see MATMiscCmdPlugin::CreateOkOrErrorReply
+ */
+TInt CATMiscCmdPlugin::CreateOkOrErrorReply( RBuf8& aReplyBuffer,
+                                            TBool aOkReply )
+    {
+    TRACE_FUNC_ENTRY
+    _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 );
+        }
+
+    aReplyBuffer.ReAlloc(aReplyBuffer.Length() + replyBuffer.Length());
+    aReplyBuffer.Append( replyBuffer );
+    TRACE_FUNC_EXIT
+    return KErrNone;
+    }
+
+/**
+ * @see MATMiscCmdPlugin::GetCharacterValue
+ */
+TInt CATMiscCmdPlugin::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;
+    }
+
+/**
+ * @see MATMiscCmdPlugin::GetModeValue
+ */
+TInt CATMiscCmdPlugin::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;
+    }
+
+void CATMiscCmdPlugin::CreateCMEReplyAndComplete(TInt aError)
+    {
+    TRACE_FUNC_ENTRY
+    
+    // TODO should return CME error according to CME state (and quiet mode?)
+    RBuf8 response;
+    response.Create(KDefaultCmdBufLength);
+    
+    // log error code
+    response.AppendNum(aError);
+    Trace(KDebugPrintD, "complete with error ", &response);
+    
+    // return error code to AT client
+    response.Zero(); // reuse RBuf
+    response.Append(KCRLF);
+    switch(aError)
+        {
+        case KErrGsm0707IncorrectPassword:
+        case KErrAccessDenied:
+            {    
+            // code was entered erroneously
+            response.Append(KCMEIncorrectPassword);
+            break;
+            }    
+        case KErrGsmSSPasswordAttemptsViolation:
+        case KErrLocked:
+            {
+            // Pin blocked 
+            response.Append(KCMEPUKRequired);
+            break;
+            }
+        case KErrGsm0707OperationNotAllowed:
+            {
+            // not allowed with this sim
+            response.Append(KCMENotAllowed);
+            break;
+            }
+        case KErrUnknown:
+            {
+            // unknown error
+            response.Append(KCMEPhoneUnknown);
+            break;
+            }
+        default:
+            response.Append(KCMEPhoneError);
+        }
+    CreateReplyAndComplete( EReplyTypeError, response );
+    response.Close();
+    TRACE_FUNC_EXIT
+    }
+
+
+TInt CATMiscCmdPlugin::HandleUnsolicitedRequest(const TDesC8& aAT )
+    {
+    return SendUnsolicitedResult(aAT);
+    }
+
+void CATMiscCmdPlugin::ConnectToEtelL(RTelServer& aTelServer, RMobilePhone& aPhone)
+    {
+    TRACE_FUNC_ENTRY
+    User::LeaveIfError(aTelServer.Connect());
+
+    // get the name of the first available phone
+    TInt phoneCount;
+    RTelServer::TPhoneInfo info;
+
+    User::LeaveIfError(aTelServer.EnumeratePhones(phoneCount));  
+    if (phoneCount < 1)
+        {
+        User::Leave(KErrNotFound); // TODO: appropriate error code
+        }
+    User::LeaveIfError(aTelServer.GetPhoneInfo(0, info));
+    User::LeaveIfError(aPhone.Open(aTelServer, info.iName));
+    TRACE_FUNC_EXIT
+    }